2016-04-24 15 views
0

Angenommen, ich habe ein "Klassen" -Objekt mit einer Eins-zu-Viele-Beziehung zu "Studenten".So wählen Sie ein einzelnes untergeordnetes Kind im Ruhezustand mit einer Zuordnung aus:

public class Class implements java.io.Serializable { 

private String classId; 
private List<Student> student; 

public Class() { 
} 

public Class(String classId) { 
    this.classId = classId; 
} 


@Id 

@Column(name = "CLASS_ID", unique = true, nullable = false, length = 10) 
public String getClassId() { 
    return this.classId; 
} 

public void setClassId(String classId) { 
    this.classId = classId; 
} 


@OneToMany(fetch = FetchType.EAGER, mappedBy="classId") 
public List<Student> getStudent() { 
    return student; 
} 

Es kann bis zu 200k "Studenten" pro Klasse geben. Ich möchte eine "Klasse" nur mit ihrem ersten Schüler abrufen. Aber wenn ich das tue, bekomme ich eine einzige "Klasse" mit ALLEN "Studenten" statt nur EINEM.

criteria = session.createCriteria(Class.class, "class").add(Restrictions.eq("class.classId", "0002")).setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); 

Dies bewirkt, dass die DB-Timeout, weil es zu lange dauert die DB mit über 200k „Students“ abfragen Gibt es eine Möglichkeit, die DB in dem Ruhezustand Abfrage eine bestimmte „Klasse“ mit nur einem abzurufen davon ist "Studenten" ohne alle 200k abzurufen, damit die DB keine Zeit vergeht? Ich würde es vorziehen, dies mit Kriterien zu tun, aber wenn nicht, gibt es eine Möglichkeit, dies mit HQL zu tun?

+3

Dies ist nicht klar 'möchte eine' Klasse 'nur mit dem ersten Schüler abrufen'. Es wird als Set abgebildet und Set behält keine Reihenfolge bei. Was meinst du mit dem ersten Studenten? Gibt es eine Spalte in der Student-Tabelle, die die Reihenfolge verwaltet? In Bezug auf die Lösung, machen Sie Ihre Assoziation als bidirektional und Sie müssen Ihre Kriterien aus 'Student.class' anstelle von' Class.class' erstellen. Sobald Sie den Schüler bekommen, können Sie zur Klasseneinheit navigieren. Das sollte helfen. –

+0

Sie haben Recht, ich sollte List nicht gesetzt verwenden. Aber können Sie mir ein Beispiel geben, wie man die bidirektionale Assoziation und die Kriterien von Student.class erstellt? – user2719805

+1

Sobald Sie es bidirektional wie beschrieben [hier] (https://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html/ch07.html#collections-bidirectional) und fügen Sie 'idx' Feld Zu Student als 'OrderColumn' können Sie' session1.createCriteria (MyStudent.class, "s") verwenden. createAlias ​​("s.myClass", "c"). add (Einschränkungen.eq ("c.id", " 1 ")). Add (Restrictions.eq (" s.idx ", 1)). SetResultTransformer (Criteria.DISTINCT_ROOT_ENTITY);' um Kriterien aus der Student.class als Beispiel zu erstellen. –

Antwort

1

Ich habe zu diesem Thema diesen sehr interessanten Artikel lesen

http://www.theotherian.com/2013/07/hibernate-joins-maxresults.html

die vorgeschlagene Lösung anwenden in diesem Artikel, um Ihr Problem:

// works with FetchType.LAZY and FetchType.EAGER 
@OneToMany(fetch = FetchType.LAZY) 
@JoinColumn(name = "CLASS_ID") 
@Fetch(FetchMode.SELECT) 
@BatchSize(size = 1) 
private List<Students> students; 

public List<Students> getStudents() { return students; } 
public void setStudents(List<Students> students) { this.students = students; } 

Ich denke, Auf diese Weise erhalten Sie eine Liste mit nur einem Schüler, der Ihre Kriterien verwendet, um einen bestimmten zu erhalten Klasse

+0

Schließt dies dann meine Optionen zum Ausfüllen von Daten, um immer nur ein Kind aktualisieren zu können, wenn ich schließlich sowohl Aktualisierungen vornehmen als auch auswählen möchte? – user2719805

+0

@ user2719805 Aber Sie müssen Studenten, die auf die Klasseneinheit zugreifen, nicht aktualisieren. Vielleicht müssen Sie den Ansatz von Madhusudana Reddy Sunnapu anwenden. – RubioRic