我正在尝试实现一个简单的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/>`
除非我flush()
在之后调用persist()
或merge()
插入未执行。这是为什么?如果删除,@Transactional
则刷新时会出现“没有正在进行的事务”的错误,但是如果删除刷新,则不会插入到数据库中。
之所以这样工作是因为您使用标记了事务为只读@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
}
}
问题内容: 我有一个托管bean,其中包含当前页面的实体对象列表。在我创建一个新对象并在事务中使用persist()将其持久保存到数据库之后;在另一个事务中,当我调用merge时(由于该实体由于先前的事务提交而处于分离状态);实体管理器无法在持久性上下文中找到对象,并向数据库抛出选择查询。我是否缺少某些东西,或者是正常行为? 更新:当我使用mysql数据库和自动生成的ID列时,存在上述问题。当我在
持久化类(Persistent Object )简称 PO,在 Hibernate 中, PO 是由 POJO(即 java 类或实体类)和 hbm 映射配置组成。 简单点说,持久化类本质上就是一个与数据库表建立了映射关系的普通 Java 类(实体类),例如 User 类与数据库中 user 表通过映射文件 User.hbm.xml 建立了映射关系,此时 User 就是一个持久化类。 持久化类的规
摘自Java Persistence with Hibernate(Manning,2007)第419页: 我应该在会话上使用持久化()吗?Hibernate会话接口还具有一个持久化()方法。它与JPA的持久化()操作具有相同的语义学。但是,这两种操作在刷新方面有一个重要的区别。在同步期间,Hibernate会话不会将持久化()操作级联到关联的实体和集合,即使您使用此选项映射了关联。它只级联到调用
特征角色 特征
我对Spring注释和persist有一个误解。我使用的是Spring3.1,带有JPA和Hibernate。我认为persist意味着将实体添加到持久性上下文中(但在提交或刷新之前不要执行任何查询),而注释意味着用事务包装方法。 然而,在这个简短的例子中,当执行指针到达持久性时,它会失败并出现异常,因为name不能为null(db约束)。 如果我交换和,一切正常。然而,我不明白为什么反过来没有,
问题内容: 我正在尝试创建事务管理器,并将其与Hibernate for Oracle一起使用。 我的persistence.xml文件是: 在spring的applicationContext.xml中,我添加了: 但是,当我运行时: 我有一个例外: Hibernate基础文件文件除外。 可能是什么问题呢? Hibernate持久性如何知道引用Spring bean? 问题答案: 持久性提供程序