从hibernate 4.3.11迁移到5.2.10并使用EntityManager而不是SessionFactory时,hibernate session.get不会加载持久对象
在一个项目中,我使用了从hibernate 4.3.11.Final和spring 4.3.1.RELEASE到maniuplating和持久化对象的一年时间。最近我迁移到hibernate 5.2.10.Final,遇到了一个描述它的问题。我有两个域类,如下所示:从hibernate 4.3.11迁移到5.2.10并使用EntityManager而不是SessionFactory时,hibernate session.get不会加载持久对象,hibernate,jpa,entitymanager,hibernate-entitymanager,Hibernate,Jpa,Entitymanager,Hibernate Entitymanager,在一个项目中,我使用了从hibernate 4.3.11.Final和spring 4.3.1.RELEASE到maniuplating和持久化对象的一年时间。最近我迁移到hibernate 5.2.10.Final,遇到了一个描述它的问题。我有两个域类,如下所示: public class Post extends BaseEntity<Long> { private String title; private Set<PostComment> comm
public class Post extends BaseEntity<Long> {
private String title;
private Set<PostComment> comments = new HashSet<>(0);
// getters and setters removed for brevity
}
public class PostComment extends BaseEntity<Long> {
private Post post;
private String descripton;
// getters and setters removed for brevity
}
public abstract class BaseEntity<T> implements Serializable {
private T id;
}
@Repository
public abstract class GenericRepository<T extends BaseEntity,PK extends Serializable> {
protected Class<T> domainClass = getDomainClass();
/* changed */
@PersistenceContext
private EntityManager em;
public Session getSession() {
/* changed */
return em.unwrap(Session.class);
}
public PK save(T Entity) {
Session session = getSession();
if(entity.getId() == null) {
session.save(entity);
}
else {
entity = (T)session.merge(entity);
session.update(entity);
}
return entity.getId();
}
public T loadByEntityId(PK entityId) {
Session session = getSession();
return (T) session.get(domainClass.getName(), entityId);
}
}
PostRepository和PostCommentRepository都是从GenericRepository扩展而来的,您可以在下面看到它:
@Repository
public class PostRepository extends GenericRepository<Post, Long> {
@Override
protected Class<Post> getDomainClass() {
return Post.class;
}
}
@Repository
public class PostCommentRepository extends GenericRepository<PostComment, Long> {
@Override
protected Class<PostComment> getDomainClass() {
return PostComment.class;
}
}
@Repository
public abstract class GenericRepository<T extends BaseEntity,PK extends Serializable> {
protected Class<T> domainClass = getDomainClass();
@Autowired
private SessionFactory sessionFactory;
public Session getSession() {
try {
return sessionFactory.getCurrentSession();
} catch (Exception e) {
}
return sessionFactory.openSession();
}
public PK save(T Entity) {
Session session = getSession();
if(entity.getId() == null) {
session.save(entity);
}
else {
entity = (T)session.merge(entity);
session.update(entity);
}
return entity.getId();
}
public T loadByEntityId(PK entityId) {
Session session = getSession();
return (T) session.get(domainClass.getName(), entityId);
}
}
在GenericRepository中,我使用EntityManager来获取会话类,如下所示:
public class Post extends BaseEntity<Long> {
private String title;
private Set<PostComment> comments = new HashSet<>(0);
// getters and setters removed for brevity
}
public class PostComment extends BaseEntity<Long> {
private Post post;
private String descripton;
// getters and setters removed for brevity
}
public abstract class BaseEntity<T> implements Serializable {
private T id;
}
@Repository
public abstract class GenericRepository<T extends BaseEntity,PK extends Serializable> {
protected Class<T> domainClass = getDomainClass();
/* changed */
@PersistenceContext
private EntityManager em;
public Session getSession() {
/* changed */
return em.unwrap(Session.class);
}
public PK save(T Entity) {
Session session = getSession();
if(entity.getId() == null) {
session.save(entity);
}
else {
entity = (T)session.merge(entity);
session.update(entity);
}
return entity.getId();
}
public T loadByEntityId(PK entityId) {
Session session = getSession();
return (T) session.get(domainClass.getName(), entityId);
}
}
现在的问题是,当我在saveAndGetDetailsCount中运行前面的方法调用时,hibernate不执行select。。。查询并将0记录为注释计数
我想知道为什么会这样
更新
也许你会问为什么我没有使用EntityManager代替Session,我使用EntityManager有一些限制
更新
当我调用saveAndGetDetailsCount时,entity参数只包含id和title,在接下来的几行中,您可以看到我希望加载注释字段并获取其大小。如果实体已附加到当前会话,为什么要生成查询
另外,为什么要调用合并和更新?你应该使用其中一种。但不是两者都有。您的问题不在迁移到hibernate 5中。我认为您的问题在事务中。当在同一事务中进行Persiste或merge调用时,loadById在方法返回之前不会执行。您可以在保存后刷新以使合并正常工作并加载对象 将您的代码更改为此
@Repository
public abstract class GenericRepository<T extends BaseEntity,PK extends Serializable> {
protected Class<T> domainClass = getDomainClass();
/* changed */
@PersistenceContext
private EntityManager em;
public Session getSession() {
/* changed */
return em.unwrap(Session.class);
}
public PK save(T Entity) {
Session session = getSession();
if(entity.getId() == null) {
em.persist(entity);
}
else {
em.merge(entity);
em.flush();
}
return entity.getId();
}
public T loadByEntityId(PK entityId) {
Session session = getSession();
return (T) session.get(domainClass.getName(), entityId);
}
}
调用合并和更新都是我的错。请检查我的第二次更新如果合并它,返回的实体将被管理,因此只需遍历子集合,就可以初始化它。我将其更改为entity=Tsession.mergeentity;,但是又没用了!合并后是否访问了关联?否,它再次记录为0,这意味着我无法访问合并后的关联。
@Repository
public abstract class GenericRepository<T extends BaseEntity,PK extends Serializable> {
protected Class<T> domainClass = getDomainClass();
/* changed */
@PersistenceContext
private EntityManager em;
public Session getSession() {
/* changed */
return em.unwrap(Session.class);
}
public PK save(T Entity) {
Session session = getSession();
if(entity.getId() == null) {
em.persist(entity);
}
else {
em.merge(entity);
em.flush();
}
return entity.getId();
}
public T loadByEntityId(PK entityId) {
Session session = getSession();
return (T) session.get(domainClass.getName(), entityId);
}
}