Ich habe eine Frage zu Hibernate und Order-by-Klausel. Ich habe eine MySQL-Datenbank mit 3 Tabellen: A, B und C. Der Java-Code für diese Tabellen ist nachfolgend.Komplexe Order-by-Klausel in .hbm Hibernate-Dateien
Klasse A Code:
package database;
import java.util.Set;
public class A implements java.io.Serializable {
private Integer id;
private Set<B> listB;
public A() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Set<B> getListB() {
return listB;
}
public void setListB(Set<B> listB) {
this.listB = listB;
}
}
Klasse B Code:
package database;
public class B implements java.io.Serializable {
private Integer id;
private A a;
private C c;
public B() {
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
public C getC() {
return c;
}
public void setC(C c) {
this.c = c;
}
}
Klasse C-Code:
package database;
public class C implements java.io.Serializable {
private Integer id;
private int num;
public C() {
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public int getNum() {
return this.num;
}
public void setNum(int num) {
this.num = num;
}
}
Die zugehörigen .hbm Dateien sind hier
Tabelle A Zuordnung:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="database">
<class name="A" table="A">
<id
column="id"
name="Id"
type="integer"
>
<generator class="increment" />
</id>
<set name="listB" cascade="all, delete-orphan" inverse="true" lazy="true" fetch="select" order-by="c.Id asc">
<key column="a_id"/>
<one-to-many class="B"/>
</set>
</class>
</hibernate-mapping>
Tabelle B-Mapping:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="database">
<class name="B" table="B">
<id
column="id"
name="Id"
type="integer"
>
<generator class="increment" />
</id>
<many-to-one name="a" class="A" fetch="select">
<column name="a_id" not-null="true" />
</many-to-one>
<many-to-one name="c" class="C" fetch="select">
<column name="c_id" not-null="true" />
</many-to-one>
</class>
</hibernate-mapping>
Tabelle C-Mapping:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="database">
<class name="C" table="C">
<id
name="Id"
type="integer"
column="id"
>
<generator class="increment"/>
</id>
<property
name="Num"
column="num"
type="integer"
not-null="true"
length="10"
/>
</class>
</hibernate-mapping>
Meine Frage bezieht sich auf die "Order-by-Klausel" in der A.hbm Datei. Ich möchte nicht nach c.Id bestellen, aber c.Num
<set name="listB" cascade="all, delete-orphan" inverse="true" lazy="true" fetch="select" order-by="c.Num asc">
Unfortunatly, wenn ich dies tun, ich die folgende Ausnahme erhalten:
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not initialize a collection: [database.A.listB#1]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.loader.Loader.loadCollection(Loader.java:2069)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:62)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:628)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:83)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1853)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:366)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:186)
at Test.main(Test.java:36)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'listb0_.c.Num' in 'order clause'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1054)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4120)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4052)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2503)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2664)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2815)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2322)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1849)
at org.hibernate.loader.Loader.doQuery(Loader.java:718)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:270)
at org.hibernate.loader.Loader.loadCollection(Loader.java:2062)
... 8 more
Ich bin hier zu überwintern, ich lese einige Dinge über Kriterien, die mir helfen könnten, aber ich sehe nicht, wie man sie in hbm-Dateien verwendet.
Danke für die Hilfe,
Lauriane
Nach den Ideen versucht du mir gegeben hast, habe ich noch nicht die Antwort. Zuerst schrieb ich die folgende Methode, um Daten in die Datenbank eingeben:
private static void create() {
A a = new A();
HibernateUtil.save(a);
C c1 = new C();
c1.setNum(5);
HibernateUtil.save(c1);
C c2 = new C();
c2.setNum(2);
HibernateUtil.save(c2);
C c3 = new C();
c3.setNum(7);
HibernateUtil.save(c3);
C c4 = new C();
c4.setNum(3);
HibernateUtil.save(c4);
B b1 = new B();
b1.setA(a);
b1.setC(c1);
HibernateUtil.save(b1);
B b2 = new B();
b2.setA(a);
b2.setC(c4);
HibernateUtil.save(b2);
B b3 = new B();
b3.setA(a);
b3.setC(c3);
HibernateUtil.save(b3);
B b4 = new B();
b4.setA(a);
b4.setC(c2);
HibernateUtil.save(b4);
A a2 = new A();
HibernateUtil.save(a2);
C c5 = new C();
c5.setNum(13);
HibernateUtil.save(c5);
C c6 = new C();
c6.setNum(11);
HibernateUtil.save(c6);
C c7 = new C();
c7.setNum(10);
HibernateUtil.save(c7);
C c8 = new C();
c8.setNum(14);
HibernateUtil.save(c8);
B b5 = new B();
b5.setA(a2);
b5.setC(c5);
HibernateUtil.save(b5);
B b6 = new B();
b6.setA(a2);
b6.setC(c8);
HibernateUtil.save(b6);
B b7 = new B();
b7.setA(a2);
b7.setC(c7);
HibernateUtil.save(b7);
B b8 = new B();
b8.setA(a2);
b8.setC(c6);
HibernateUtil.save(b8);
}
Es gibt mir zwei Instanzen von A, das jeweils mit einer Liste von vier Instanzen von B.
Dann habe ich versucht, diesen Code:
Criteria crit = HibernateUtil.currentSession().createCriteria(A.class);
Criteria critb = crit.createCriteria("listB");
Criteria critc = critb.createCriteria("c");
critc.addOrder(Order.asc("num"));
List<A> list = critc.list();
// Code to iterate over listA
for (A a : list) {
List<B> listB = a.getListB();
for (B b : listB) {
System.out.print(b.getC().getNum() + ", ");
}
System.out.println();
}
Die Liste I erhalten enthält 4 mal jede Instanz von A, und der Ausgang ist:
2, 7, 3, 5,
2, 7, 3, 5,
2, 7, 3, 5,
2, 7, 3, 5,
14, 13, 10, 11,
14, 13, 10, 11,
14, 13, 10, 11,
14, 13, 10, 11,
Also habe ich versucht, den Getter zu ändern ListeB in der A-Klasse an:
public List<B> getListB() {
Criteria crit =
HibernateUtil.currentSession().createCriteria(B.class);
Criteria critc = crit.createCriteria("c");
critc.addOrder(Order.asc("num"));
return critc.list();
}
und führen Sie den folgenden Code ein:
List<A> list = (List<A>) HibernateUtil.getList("from A");
for (A a : list) {
List<B> listB = a.getListB();
for (B b : listB) {
System.out.print(b.getC().getNum() + ", ");
}
System.out.println();
}
Und der Ausgang war:
2, 3, 5, 7, 10, 11, 13, 14,
2, 3, 5, 7, 10, 11, 13, 14,
Es gibt keinen Unterschied zwischen den Instanzen von B refering auf die eine oder andere Instanz von A, und ich sehe nicht, wie es funktionieren könnte gemacht ist ..
.Danke für Ihre Hilfe,
Lauriane
mit Anmerkungen und JPA beginnen kann ich denke, es könnte hilfreich sein, wenn Sie sich die von Hibernate generierte SQL ansehen und posten. – Carsten