[英]Spring-Hibernate persist does not result in insert
我正在嘗試實現一個簡單的DAO。 我有道:
@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;
}
一個實體:
@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;
}
}
這是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/>`
除非我在persist()
或merge()
flush()
之后調用flush()
,否則insert不會執行。 這是為什么? 如果我刪除@Transactional
然后我在刷新時遇到“沒有事務正在進行中”的錯誤,但是如果刪除flush則沒有插入到DB中。
它以這種方式工作,因為您使用@Transactional(readOnly = true)
將事務標記為只讀。
正如您所看到的,它不會使您的事務實際上是只讀的,因為您仍然可以通過手動調用flush()
來保持更改。 但是,它會在事務結束時禁用自動刷新,因此如果沒有手動刷新,則不會保留更改。
您需要從類級別注釋中刪除readOnly
,或者在具有方法級注釋的非只讀方法上覆蓋它:
@Override
@Transactional(readOnly = false)
public boolean save(User user) { ... }
另請注意,事務划分通常應用於服務層方法,而不是DAO方法。 特別是,在編寫DAO方法時,您實際上不知道哪些事務應該是只讀的,哪些不是。 此信息僅在設計服務層時可用,如本例中所示:
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
}
}
嘗試將事務傳播設置為required,並刪除所有flush()
: -
@Repository("iUserDao")
@Transactional(propagation=Propagation.REQUIRED)
public class UserDao implements IUserDao {
...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.