Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从hibernate 4.3.11迁移到5.2.10并使用EntityManager而不是SessionFactory时,hibernate session.get不会加载持久对象_Hibernate_Jpa_Entitymanager_Hibernate Entitymanager - Fatal编程技术网

从hibernate 4.3.11迁移到5.2.10并使用EntityManager而不是SessionFactory时,hibernate session.get不会加载持久对象

从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

在一个项目中,我使用了从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> 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);
    }
}