Hibernate查询嵌套对象时忽略注释的位置

时间:2016-07-18 09:34:28

标签: java hibernate jpa entitymanager hibernate-entitymanager

我注意到我的模型中有这种奇怪的行为。 (这是我的模特):

@Entity(name = "A")
public class A {

    @Id
    public String aId = UUID.randomUUID().toString();

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "aId")
    public Set<B> b = new HashSet<>();
}

@Entity(name = "B")
public class B {
    @Id
    public String bId = UUID.randomUUID().toString();
    public String aId;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "cId")
    @NotFound(action = NotFoundAction.IGNORE)
    public C obj;
}

@Entity(name = "C")
@Where(clause = "ran = 'hello'")
public class C {
    @Id
    public String cId = UUID.randomUUID().toString();

    public String ran = UUID.randomUUID().toString();

    public LocalDateTime start;
}

所以:A类有一个B的集合,它引用了C.

C有一个注释&#34;其中&#34;总是评估为false。

考虑这个测试用例:

    @Test
    public void test() throws IOException {

        Provider<EntityManager> provider = injector.getProvider(EntityManager.class);
        EntityManager em = provider.get();

        em.getTransaction().begin();

        A a = new A();
        B b = new B();
        b.aId = a.aId;
        a.b.add(b);
        C c = new C();
        b.obj = c;
        c.start = LocalDateTime.now().minusDays(10);
        em.persist(a);
        em.persist(b);
        em.persist(c);

        em.getTransaction().commit();

        em.clear();

        em.getTransaction().begin();

        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<B> createQuery = cb.createQuery(B.class);
        Root<B> from = createQuery.from(B.class);
        CriteriaQuery<B> select = createQuery.select(from);


        List<B> resultList = em.createQuery(createQuery).getResultList();
        em.getTransaction().commit();

        resultList.forEach( b2 -> {
            Assert.assertNull(b2.obj); // This is correct
        });

        em.clear();

        em.getTransaction().begin();
        CriteriaBuilder cb2 = em.getCriteriaBuilder();
        CriteriaQuery<A> createQuery2 = cb2.createQuery(A.class);
        Root<A> from2 = createQuery2.from(A.class);
        createQuery2.select(from2);

        List<A> resultList2 = em.createQuery(createQuery2).getResultList();

        resultList2.forEach( a2 -> {
            a2.b.forEach( b2 -> {
                Assert.assertNull(b2.obj); // this should be null but is not
            });
        });

    }

所以我在做:

  • 添加所有型号:A,B和C,并设置属性。

测试1:

查询类型B的所有对象。正确应用where子句并且不解析C.

测试2:

查询类型A的所有对象.B已正确解析,但是引用B-> C忽略了where子句。

这肯定不正确吗?或者我错过了什么?

编辑:

更多的测试显示,在B - C关系中将提取策略设置为LAZY可以修复此问题(但我不知道为什么)。

0 个答案:

没有答案