опять мой мозг менее силен, чем логика ....
Мой пример имеет связь один ко многим, когда у Человека много вещей.
Элемент имеет свойство Date. Я хочу сделать запрос, в котором извлекается дерево объектов Персоны с определенным связанным набором Предметов, то есть «запрашивать Персоны с Предметами, у которых Дата больше 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) +"]";
}
}
}
Для полноты вот мой файл 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>
@ Амир Пашазаде, 1-й комментатор:
Спасибо за быстрый ответ, Амир. Тестовый случай 'testQueryTheItems' выполняет запрос элементов. После получения списка результатов Предметов я ссылаюсь на связанного с множеством людей человека. Этот человек наоборот ссылается на все связанные предметы. Я хотел бы иметь только один элемент из предыдущего запроса, связанный с человеком.
Это касается транзакционных границ? Тип установленных лиц: org.hibernate.collection.internal.PersistentSet. Так это все еще EAGER / LAZY, выбирающий ссылочные позиции?
Если бы я сейчас завершил транзакцию, можно ли было бы иметь только один предмет, связывающий одного человека, связывающий один предмет?