我的大腦比邏輯強大少....JPA查詢與取/聯接再次檢索只有某些協會
我的例子有一個一對多的關聯,當一個人有很多項目。 一個物品有一個日期屬性。我想做一個查詢,其中具有確定的相關聯的一組項目的人的對象樹被檢索,即'查詢具有大於xyz的日期的項目的人員'。
每個測試方法的最後一個斷言失敗。但它表達了我想達到的目標。
會很高興幫助我在這裏。或者,甚至我的整個想法在這裏都不對? 我假定目標是檢索從數據庫中提取的工作單元所需的對象。不多或少。工作完成後,操作對象將被合併。
我上傳了項目here。 這是Maven2。並且可以運行:MVN測試
感謝您的幫助wringng M個大腦:-)
這裏是我的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) +"]";
}
}
}
爲了完整起見,這裏是我的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>
@Amir Pashazadeh,第一個評論者:
感謝您的快速銷售代表埃米爾。測試用例'testQueryTheItems'確實查詢項目。在收到物品的結果清單後,我會參考多對一的相關人員。這個人反之亦然引用所有相關的項目。我想從與該人關聯的前一個查詢中獲得單個項目。 它處理事務性邊界嗎? Person的類型是org.hibernate.collection.internal.PersistentSet。那麼這仍然是EAGER/LAZY獲取引用的項目嗎? 如果我現在要結束交易,是否有可能只有一個項目與一個人相關聯,從而將一個項目關聯起來?
嘗試查詢項目,然後導航到人員,這將幫助您只有滿足條件的項目才能在查詢結果中 – 2012-02-27 21:13:07