Hallo zusammen,
ich versuche gerade Hibernate zu verstehen. Die Standardfälle für OneToMany habe ich schon verstanden. Allerdings habe ich eine Anforderung, bei der ich überhaupt nicht weiß, ob bzw. wie man das mit Hibernate umsetzt.
Es geht um eine OneToMany-Beziehung, in der es eine große Anzahl von Kind-Objekten gibt (im Extremfall hoher 5-stellige Anzahl). Über eine ReST-API soll ein „Paging“ implementiert werden, d.h. der Vater und ein kleiner Teil seiner Kinder sollen zurückgegeben werden. Wie holt man die Daten aus der Datenbank, ohne direkt alle Kinder im Speicher zu haben?
Beispiel: Vater hat viele Kinder verschiedenen Alters. Wie kriege ich den Vater mit den beiden ältesten Kindern?
Ich könnte mir vorstellen, dass das über JPQL geht?!? Aber das verstehe ich noch nicht genau bzw. habe ich noch nicht zum Laufen gebracht. Ich bitte um Unterstützung
Gibt es sonst etwas zu beachten beim Umgang mit sehr vielen Kind-Objekten?
Hier mal ein konkretes Beispiel
Main.java
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class Main {
private static final EntityManagerFactory entityManagerFactory;
static {
try {
entityManagerFactory = Persistence
.createEntityManagerFactory("test");
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static void main(String[] args) {
EntityManager em = getEntityManager();
try {
Child child1 = new Child("A", 11);
Child child2 = new Child("B", 12);
Child child3 = new Child("C", 13);
Child child4 = new Child("D", 14);
Child child5 = new Child("E", 15);
Father father = new Father("Father", child1, child2, child3,
child4, child5);
persistFather(em, father);
Father persistedFather = findFather(em, father.getId());
printFather(persistedFather);
} finally {
em.close();
}
}
private static Father findFather(EntityManager em, long id) {
Father fatherFound = null;
try {
em.getTransaction().begin();
fatherFound = em.find(Father.class, id);
em.getTransaction().commit();
} catch (Exception e) {
em.getTransaction().rollback();
}
return fatherFound;
}
private static void persistFather(EntityManager em, Father father) {
try {
em.getTransaction().begin();
em.persist(father);
em.getTransaction().commit();
} catch (Exception e) {
em.getTransaction().rollback();
}
}
private static void printFather(Father fatherFound) {
System.out.println("Father " + fatherFound.getFirstName() + " has "
+ fatherFound.getChildren().size() + " sons");
for (Child child : fatherFound.getChildren()) {
System.out.println("- " + child.getFirstName() + ", "
+ child.getAge() + " years old");
}
}
public static EntityManager getEntityManager() {
return entityManagerFactory.createEntityManager();
}
}```
**Father.java**
```import java.util.Collection;
import java.util.LinkedList;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
@Entity
public class Father {
@Id
@GeneratedValue
private long id;
private String firstName;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "father_id_fk")
private Collection<Child> children;
public Father() {
children = new LinkedList<>();
}
public Father(String firstName, Child... children) {
this();
this.firstName = firstName;
for (Child child : children) {
this.children.add(child);
}
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Collection<Child> getChildren() {
return children;
}
public void setChildren(Collection<Child> children) {
this.children = children;
}
}```
**Child.java**
```import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Child {
@Id
@GeneratedValue
private long id;
private String firstName;
private int age;
public Child(String firstName, int age) {
this.firstName = firstName;
this.age = age;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}```
**persistence.xml**
[XML]<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_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:postgresql://localhost:5432/hibernatetest" />
<property name="javax.persistence.jdbc.user" value="user" />
<property name="javax.persistence.jdbc.password" value="password" />
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
</properties>
</persistence-unit>
</persistence>[/XML]