Spring -Hibernate persist does not insert

I am trying to implement a simple DAO. I have a Tao:

@Repository("iUserDao") @Transactional(readOnly = true) public class UserDao implements IUserDao { private EntityManager entityManager; @PersistenceContext public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } @Override public User getById(int id) { return entityManager.find(User.class, id); } @Override public boolean save(User user) { entityManager.persist(user); entityManager.flush(); return true; } @Override public boolean update(User user) { entityManager.merge(user); entityManager.flush(); return true; } @Override public boolean delete(User user) { user = entityManager.getReference(User.class, user.getId()); if (user == null) return false; entityManager.remove(user); entityManager.flush(); return true; } 

And the essence:

 @Entity @Table(name = "users") public class User { private int id; private Date creationDate; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public int getId() { return id; } public User() { } public User(Date creationDate) { this.creationDate = creationDate; } public void setId(int id) { this.id = id; } public Date getCreationDate() { return creationDate; } public void setCreationDate(Date creationDate) { this.creationDate = creationDate; } } 

Here appContext.xml: `

 <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter" p:persistenceUnitName="test"> <property name="loadTimeWeaver"> <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="entityManagerFactory"/> <bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" p:database="MYSQL" p:showSql="true"/> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/> <tx:annotation-driven/>` 

If I do not call flush() after persist() or merge() , then the insertion fails. Why is this? If I delete @Transactional , then I get the error message โ€œNo transaction is executedโ€ on the flash, but if I delete the flash nothing is inserted into the database.

+6
java spring hibernate
source share
2 answers

This works because you marked the transaction as read only with @Transactional(readOnly = true) .

As you can see, this does not make your transactions virtually read-only, as you can still save changes by calling flush() manually. However, it disables automatic reset at the end of the transaction, so changes are not saved without a manual reset.

You need to either remove readOnly from the class level annotation, or override it for non-read methods with method level annotations:

 @Override @Transactional(readOnly = false) public boolean save(User user) { ... } 

Also note that transaction demarcation is usually applied to service level methods, not DAO methods. In particular, when writing DAO methods, you actually do not know which transactions should be read-only and which should not. This information is only available when developing a service level, as you can see in this example:

 public class UserService { @Autowired UserDAO dao; @Transactional(readOnly = true) public User getUserById(int id) { return dao.getById(id); // getById() can participate in effectively read-only transaction } @Transactional public void changeUserName(int id, String newName) { User u = dao.getById(id); // Or not u.setName(newName); // Change will be flushed at the end of transaction } } 
+10
source share

Try adjusting the transactional distribution to the required one and delete all flush() : -

 @Repository("iUserDao") @Transactional(propagation=Propagation.REQUIRED) public class UserDao implements IUserDao { ... } 
+1
source share

All Articles