Java 仅检索特定关联的带抓取/连接的JPA查询

Java 仅检索特定关联的带抓取/连接的JPA查询,java,jpa,fetch,Java,Jpa,Fetch,再一次,我的大脑没有逻辑那么强大 我的示例有一个一对多的关联,其中一个人有许多项。 项目具有日期属性。我想做一个查询,其中检索具有已确定关联项集的人员的对象树,即“查询具有日期大于xyz的项目的人员” 每个测试方法的最后一个断言失败。但它表达了我想要实现的目标 在这里帮我会很高兴的。还是我的整个想法都错了? 我假设目标是从数据库中获取工作单元所需的对象。不多也不少。工作完成后,将合并操纵对象 我上传了这个项目。 这是Maven2。并且可以使用:mvn test运行 谢谢你帮我绞尽脑汁:-) 以下

再一次,我的大脑没有逻辑那么强大

我的示例有一个一对多的关联,其中一个人有许多项。 项目具有日期属性。我想做一个查询,其中检索具有已确定关联项集的人员的对象树,即“查询具有日期大于xyz的项目的人员”

每个测试方法的最后一个断言失败。但它表达了我想要实现的目标

在这里帮我会很高兴的。还是我的整个想法都错了? 我假设目标是从数据库中获取工作单元所需的对象。不多也不少。工作完成后,将合并操纵对象

我上传了这个项目。 这是Maven2。并且可以使用:mvn test运行

谢谢你帮我绞尽脑汁:-)

以下是我的Junit测试:

package de.greyshine.jpaSelectJoinDate;

import java.util.*;
import javax.persistence.*;
import junit.framework.Assert;
import org.junit.*;

public class Tester {

    EntityManager em;

    static final Date DATE1 = createDate(2012, Calendar.JANUARY, 1);
    static final Date DATE2 = createDate(2012, Calendar.MARCH, 1);

    static Date createDate(int inYear, int inMonth, int inDayOfMonth) {
        final Calendar theCalendar = Calendar.getInstance();
        theCalendar.set( Calendar.YEAR, inYear);
        theCalendar.set( Calendar.MONTH, inMonth);
        theCalendar.set( Calendar.DAY_OF_MONTH, inDayOfMonth);
        return theCalendar.getTime();
    }

    @Before
    public void _junitBeforeClass() {
        final EntityManagerFactory emf = Persistence.createEntityManagerFactory( "testPu" ); ;
        em = emf.createEntityManager();
        em.setFlushMode( FlushModeType.COMMIT );

        final Person p = new Person();
        final Item i1 = new Item();
        i1.date = DATE1;
        i1.person = p;
        final Item i2 = new Item();
        i2.date = DATE2;
        i2.person = p;
        p.items.add( i1 );
        p.items.add( i2 );

        em.getTransaction().begin();
        em.persist( i1 );
        em.persist( i2 );
        em.persist( p );
        em.getTransaction().commit();
    }

    @Test
    public void testQueryTheItems() {

        em.getTransaction().begin();
        final Query theQuery = em.createQuery( "FROM Tester$Item i WHERE i.date > :inDate" );

        theQuery.setParameter( "inDate" , DATE1, TemporalType.TIMESTAMP);
        @SuppressWarnings("unchecked")
        final List<Item> theResults = (List<Item>)theQuery.getResultList();
        em.getTransaction().commit();
        Assert.assertEquals( 1, theResults.size() );
        Item theItem = theResults.iterator().next();
        Assert.assertEquals( theItem.date.getTime(), DATE2.getTime() );
        Assert.assertNotNull( theItem.person );
        Assert.assertEquals( 1, theItem.person.items.size() );
    }

    @Test
    public void testQueryThePerson() {

        em.getTransaction().begin();
        final Query theQuery = em.createQuery( "FROM Tester$Person p JOIN FETCH p.items i WHERE i.date > :inDate" );

        theQuery.setParameter( "inDate" , DATE1, TemporalType.TIMESTAMP);
        @SuppressWarnings("unchecked")
        final List<Person> theResults = (List<Person>)theQuery.getResultList();
        em.getTransaction().commit();
        Assert.assertEquals( 1, theResults.size() );
        Person thePerson = theResults.iterator().next();
        System.out.println( thePerson );
        Assert.assertEquals( 1, thePerson.items.size() );
    }

    @Entity
    @Table( name="persons" ) 
    public static class Person {

        @Id
        @GeneratedValue
        public Long id;

        @OneToMany
        final Set<Item> items = new HashSet<Item>(); 

        @Override
        public String toString() {
            return "Person [items="+ items +"]";
        }
    }

    @Entity
    @Table( name="items" ) 
    public static class Item {

        @Id
        @GeneratedValue
        public Long id;

        @Column
        @Temporal( TemporalType.TIMESTAMP )
        Date date;

        @ManyToOne
        Person person;

        @Override
        public String toString() {
            return "Item [id="+id+"; date="+ date +"; person.id="+ (person==null?null:person.id) +"]";
        }
    }
}
package de.greyshine.jpaSelectJoinDate;
导入java.util.*;
导入javax.persistence.*;
导入junit.framework.Assert;
导入org.junit.*;
公共类测试员{
实体管理器;
静态最终日期1=createDate(2012年1月1日日历);
静态最终日期2=createDate(2012年3月1日日历);
静态日期createDate(年内整数、月内整数、月内整数){
final Calendar theCalendar=Calendar.getInstance();
日历设置(日历年,单位为年);
Calendar.set(Calendar.MONTH,in MONTH);
Calendar.set(日历月日,inDayOfMonth);
返回calendar.getTime();
}
@以前
public void_junitBeforeClass(){
final EntityManagerFactory emf=Persistence.createEntityManagerFactory(“testPu”);
em=emf.createEntityManager();
em.setFlushMode(FlushModeType.COMMIT);
最终人员p=新人员();
最终项目i1=新项目();
i1.日期=日期1;
i1.人=p;
最终项目i2=新项目();
i2.日期=日期2;
i2.1人=p;
p、 增加第(1)项;
p、 增加(i2);
em.getTransaction().begin();
em.persist(i1);
em.persist(i2);
em.p;
em.getTransaction().commit();
}
@试验
公共void testQueryTheItems(){
em.getTransaction().begin();
最终查询theQuery=em.createQuery(“来自Tester$Item i,其中i.date>:inDate”);
setParameter(“inDate”,DATE1,TemporalType.TIMESTAMP);
@抑制警告(“未选中”)
最终列表theResults=(List)theQuery.getResultList();
em.getTransaction().commit();
Assert.assertEquals(1,theResults.size());
Item Item=theResults.iterator().next();
Assert.assertEquals(item.date.getTime(),DATE2.getTime());
Assert.assertNotNull(item.person);
Assert.assertEquals(1,item.person.items.size());
}
@试验
public void testQueryThePerson(){
em.getTransaction().begin();
最终查询theQuery=em.createQuery(“从测试仪$Person p JOIN FETCH p.items i其中i.date>:inDate”);
setParameter(“inDate”,DATE1,TemporalType.TIMESTAMP);
@抑制警告(“未选中”)
最终列表theResults=(List)theQuery.getResultList();
em.getTransaction().commit();
Assert.assertEquals(1,theResults.size());
Person thePerson=theResults.iterator().next();
System.out.println(个人);
Assert.assertEquals(1,person.items.size());
}
@实体
@表(name=“persons”)
公共静态类人员{
@身份证
@生成值
公共长id;
@独身癖
最终设置项=新HashSet();
@凌驾
公共字符串toString(){
返回“Person[items=“+items+””;
}
}
@实体
@表(name=“items”)
公共静态类项{
@身份证
@生成值
公共长id;
@纵队
@时态(TemporalType.TIMESTAMP)
日期;
@许多酮
个人;
@凌驾
公共字符串toString(){
return“Item[id=“+id+”;date=“+date+”;person.id=“+(person==null?null:person.id)+“]”;
}
}
}
为了完整起见,这里是my persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
                        http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="applicationManagedPersistenceUnit" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>de.greyshine.jpaauction.entity.Buyer</class>
        <class>de.greyshine.jpaauction.entity.Seller</class>
        <class>de.greyshine.jpaauction.entity.Item</class>
        <class>de.greyshine.jpaauction.entity.Bid</class>
        <properties>
            <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:unit-testing-jpa" />
            <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="create" />
            <property name="hibernate.connection.username" value="sa" />
            <property name="hibernate.connection.password" value="" />
        </properties>
    </persistence-unit>
</persistence>

org.hibernate.ejb.HibernatePersistence
de.greyshine.jpa生产.实体.买方
de.greyshine.jpaauction.entity.Seller
de.greyshine.jpaauction.entity.Item
de.greyshine.jpaauction.entity.Bid
@Amir Pashazadeh,第一评论员:

谢谢你的快速回复,阿米尔。testcase“testQueryTheItems”确实查询这些项。在收到项目结果列表后,我将多个项目引用给一个相关人员。此人引用所有相关项目,反之亦然。我只想将前一个查询中的单个项与此人关联。 它是否处理事务边界?人员集的类型为org.hibernate.collection.internal.PersistentSet。那么,这仍然是急切/懒惰地获取引用项吗? 如果我现在结束交易,是否可以只让一个项目关联一个人,关联一个项目?

ha, 阿米尔是鼓舞人心的助手。是的,它与德克萨斯州边界进行交易。它进行了以下更改以使其正常工作:

public class Tester {

    static final EntityManagerFactory emf = Persistence.createEntityManagerFactory( "testPu" ); ;
    EntityManager em;

    ...     

    @BeforeClass
    public static void _junitBeforeClass() {
        final EntityManager em = emf.createEntityManager();
        em.setFlushMode( FlushModeType.COMMIT );

        final Person p = new Person();
        final Item i1 = new Item();
        i1.date = DATE1;
        i1.person = p;
        final Item i2 = new Item();
        i2.date = DATE2;
        i2.person = p;
        p.items.add( i1 );
        p.items.add( i2 );

        em.getTransaction().begin();
        em.persist( i1 );
        em.persist( i2 );
        em.persist( p );
        em.getTransaction().commit();

        em.close();
    }

    @Before
    public void _junitBefore() {
        em = emf.createEntityManager();
        em.setFlushMode( FlushModeType.COMMIT );
    }

    @After
    public void _junitAfter() {
        em.close();
    }
...
实体经理负责我的工作单位。当一个工作单元启动时,EntityManager由EntityManager工厂创建并随后关闭!这是我真正的TX边界,而不是EntityManager事务的提交。 …我以前没读过吗。。。一百万次…:-) “testQueryThePerson”测试会通过的。我猜是对的。 另一方面,“testQueryTheItems”测试根本不会通过,但取决于