我有一个关于hibernate和order-by子句的问题.
我有一个包含3个表的MysqL数据库:A,B和C.以下是与这些表对应的Java代码.
A类代码:
package database;
import java.util.Set;
public class A implements java.io.Serializable {
private Integer id;
private Set
B类代码:
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;
}
}
C类代码:
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;
}
}
相关的.hbm文件在这里
表A映射:
表B映射:
表C映射:
我的问题是关于A.hbm文件中的“order-by”子句.我想订购不跟随c.Id,但c.Num
不幸的是,当我这样做时,我得到以下异常:
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
我是hibernate的新手,我读了一些可以帮助我的标准,但是我没有看到如何将它们用于hbm文件.
谢谢你的帮助,
Lauriane
在尝试了你给我的想法后,我仍然没有答案.首先,我编写了以下方法将数据输入数据库:
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);
}
它给了我2个A的实例,每个实例都有4个B实例的列表.
然后,我尝试了这段代码:
Criteria crit = HibernateUtil.currentSession().createCriteria(A.class);
Criteria critb = crit.createCriteria("listB");
Criteria critc = critb.createCriteria("c");
critc.addOrder(Order.asc("num"));
List
我获得的列表包含A的每个实例4次,输出为:
2,7,3,5,2,14,13,10,11,
所以我尝试将A类中的listB的getter更改为:
public List
并运行以下代码:
List
输出是:
2,
B的实例引用A的一个或另一个实例之间没有区别,我看不出它是如何工作的……
谢谢你的帮助,
Lauriane
>在A中按条款命令
>您将无法在A上设置C的顺序,因为A未直接连接到C.
>它为c.id工作的原因是因为B包含列c_id(C类映射),order by子句应用于表B上的c_id列而不是c上的id列
>当你设置c.num时,hibernate将尝试在表B中查找我们没有的列.
>标准查询
>要使用条件查询,请首先从A中删除order-by子句或使用有效的子句
>标准查询将在java代码中使用“session”创建,而不是在hbm文件中配置.
示例代码
Criteria crit = session.createCriteria(A.class);
Criteria critb = crit.createCriteria("listB");
Criteria critc = critb.createCriteria("c");
critc.addOrder(Order.asc("num"));
List
>如果b表可以被视为中间表,在这种情况下不需要B类,A可以使用连接表b(http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/associations.html#assoc-bidirectional-join)与C关联,那么您可以在hbm文件中使用order-by子句,如下所示:
A.java
// remove listB and add following
private Set
A的映射
// remove listB mapping and add following
Java代码
Criteria crit = session.createCriteria(A.class);
List
唯一的缺点是B不能独立管理,你需要从B中删除列“id”,并将a_id和c_id作为复合主键进行插入/更新/删除操作,对于选择查询,上面的更改就足够了.
>欲了解更多详情,请参阅:http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querycriteria.html
>除Criteria Query外,您还可以使用hbm查询:http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html
>您也可以开始使用注释和JPA