如何从Hibernate会话中删除不需要的实体?

dwa*_*ohn 12 java spring hibernate jpa lazy-initialization

我试图Entity1通过查询映射的实体来获取它.我正在使用CriteriaBuilder如下所示执行此操作

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Entity1> createQuery = criteriaBuilder.createQuery(Entity1.class);
Root<Entity1> root = createQuery.from(Entity1.class);
Join<Entity1, MappedEntity2> mappedEntity2Join = root.join("mappedEntity2");
createQuery.select(root);

predicate = criteriaBuilder.and(predicate, criteriaBuilder.equal(root.get(COL_USER_ID), userId));

// where clause to filter by query params
createQuery.where(predicate).distinct(true);
createQuery.getRestriction();

TypedQuery<Entity1> query = entityManager.createQuery(createQuery);
Run Code Online (Sandbox Code Playgroud)

但在随机的情况下,我发现查询是在"Entity2.entities1"上执行的,而没有在join中指定Entity2.我的猜测是Entity2已经在会话中可用,并且它使用entities1进行了懒惰的初始化.因此,Criteria会为Entity2而不是Entity1生成查询.

有没有办法限制条件查询Entity1?或者如何在执行此特定条件之前从会话中删除Entity2.

预期查询,

select * 
from Entity1 obj1_ 
inner join mappedEntity1 mObj_ on obj1_.obj_id=mObj_.id 
where obj1_.id=?
Run Code Online (Sandbox Code Playgroud)

但查询生成为,

select * 
from entities1_entities2 obj0_ 
inner join Entity1 obj1_ on obj0_.obj_id=obj1_.id 
where obj0_.entity2_id=?
Run Code Online (Sandbox Code Playgroud)

实体结构:

public class Entity1 {

    @ManyToOne
    MappedEntity1 mappedEntity1;

    @OneToMany
    MappedEntity2 mappedEntity2;

    @OneToMany
    MappedEntity3 mappedEntity3;

}
Run Code Online (Sandbox Code Playgroud)

public class Entity2 {

    @OneToMany
    List<Entity1> entities1;

    @OneToOne
    MappedEntity2 mappedEntity2;

}
Run Code Online (Sandbox Code Playgroud)

Entity1和Entity2的参考表

表名:entities1_entities2

entity1_id INTEGER NOT NULL,
entity2_id INTEGER NOT NULL,
CONSTRAINT entities1_entities2_entity1_id_fkey FOREIGN KEY (entity1_id)
REFERENCES entity1 (id),
CONSTRAINT entities1_entities2_entity2_id_fkey FOREIGN KEY (entity2_id)
    REFERENCES entity2 (id)
Run Code Online (Sandbox Code Playgroud)

Var*_*ain 0

首先,在查询新实体之前,您需要检查旧实体是否存在。您可以直接尝试将实体传递给 session.delete(),以删除该对象。如果数据库中没有找到需要处理的记录,则应该出现异常。事实上,我们通常并没有真正理解这种情况。我们总是删除一个现有的实体,我的意思是通常的逻辑是这样的;因此,如果已经完成,则无需这样做。你可以简单地这样做,

Entity1 ent = session.load(Entity1.class, '1234');
session.delete(ent);
Run Code Online (Sandbox Code Playgroud)

或者你也可以这样做,

Entity1 ent = new Entity1('1234'); // used constructor for brevity
session.delete(ent);
Run Code Online (Sandbox Code Playgroud)

顺便说一下,你也可以使用这个版本的session.delete(String query),

session.delete("from Entity1 e where e.id = '1234'"); // Just found it is deprecated
Run Code Online (Sandbox Code Playgroud)