hibernate一对多,不能根据 一的那方 得到 多的那方

拉轰的大蜗牛 2017-01-08 11:17:42
下面是问题简述, 希望有大神不吝赐教.
User类属性(one)
private String user_id;//主键
private String name;
private String password;
private String preference;
private List<Order> orders;//订单集合
Order类属性(many)
private String order_id;//主键
private BigDecimal price;
private Date createDatetime;
private User user;//外键
private String backup;

USER xml配置
<hibernate-mapping
package="com.hbt3.entity">

<class name="User" table="t_user" lazy="true">

<id name="user_id" column="user_id">
<generator class="native"/>
</id>
<!-- <property name="userId" column="user_id"/> -->
<property name="name"/>
<property name="password"/>
<property name="preference"/>
<list name="orders" inverse="true" cascade="all" lazy="true">
<key column="user_id" ></key><!-- 一对多,多方的外键列 -->
<index column="order_id" type="java.lang.String"></index>
<one-to-many class="com.hbt3.entity.Order"/>
</list>
</class>
</hibernate-mapping>
Order xml配置
<hibernate-mapping package="com.hbt3.entity">
<class name="Order" table="t_order" lazy="true">

<id name="order_id" column="order_id">
<generator class="native"/>
</id>
<property name="price" column="price"/>
<property name="createDatetime"/>
<property name="backup"/>
<many-to-one name="user" class="com.hbt3.entity.User" outer-join="true" >
<column name="user_id"></column>
</many-to-one>
</class>

</hibernate-mapping>


// 下面是一个测试方法代码片段
public static void query(){
Session session = HibernateUtil.getSession();// 获取session会话对象
session.beginTransaction();// 开始一个事务

String hql = " from User where name = ? ";

Query hqlQuery = session.createQuery(hql);// hql查询接口
hqlQuery.setParameter(0, "黄某");

List userList = hqlQuery.list();
Iterator iter = userList.iterator();
while(iter.hasNext()) {
User user=(User) iter.next();
System.out.println("user.name=" + user.getName());
System.out.println("user.orders=" + user.getOrders().size()); // ***为何无法拿到order****
}

if(session != null){
session.close();
}
}


下面是测试方法执行的控制台打印信息:
Hibernate: select user0_.user_id as user1_1_, user0_.name as name1_, user0_.password as password1_, user0_.preference as preference1_ from t_user user0_ where user0_.name=?
user.name=黄某
Hibernate: select orders0_.user_id as user5_1_, orders0_.order_id as order1_1_, orders0_.order_id as order1_0_0_, orders0_.price as price0_0_, orders0_.createDatetime as createDa3_0_0_, orders0_.backup as backup0_0_, orders0_.user_id as user5_0_0_ from t_order orders0_ where orders0_.user_id=?
Exception in thread "main" org.hibernate.exception.GenericJDBCException: could not initialize a collection: [com.hbt3.entity.User.orders#91E08E9141054A199E88C654777A906C]
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:126)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:114)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.loader.Loader.loadCollection(Loader.java:2026)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:59)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:587)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:83)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1744)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:366)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:131)
at org.hibernate.collection.PersistentList.size(PersistentList.java:114)
at com.hbt3.app.One2Many.query(One2Many.java:35)
at com.hbt3.app.One2Many.main(One2Many.java:17)
Caused by: java.sql.SQLException: 无法转换为内部表示
at oracle.jdbc.driver.CharCommonAccessor.getInt(CharCommonAccessor.java:147)
at oracle.jdbc.driver.T4CVarcharAccessor.getInt(T4CVarcharAccessor.java:815)
at oracle.jdbc.driver.OracleResultSetImpl.getInt(OracleResultSetImpl.java:896)
at oracle.jdbc.driver.OracleResultSet.getInt(OracleResultSet.java:434)
at org.hibernate.type.IntegerType.get(IntegerType.java:51)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:184)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:173)
at org.hibernate.persister.collection.AbstractCollectionPersister.readIndex(AbstractCollectionPersister.java:730)
at org.hibernate.collection.PersistentList.readFrom(PersistentList.java:402)
at org.hibernate.loader.Loader.readCollectionElement(Loader.java:1031)
at org.hibernate.loader.Loader.readCollectionElements(Loader.java:669)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:614)
at org.hibernate.loader.Loader.doQuery(Loader.java:724)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.loadCollection(Loader.java:2019)
... 10 more
...全文
337 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
江峰_Fight 2017-10-13
  • 打赏
  • 举报
回复
hql直接打印就行,为什么你还要循环打印呢? private static void function(){ Session session = HibernateUtil.getCurrentSession(); Transaction transaction = session.beginTransaction(); String string="from com.bd.bean.Customer"; // String string2="from Customer where cust_id=2"; // String string="from Customer where cust_id=?"; // String string="from Customer where cust_id=:cust_id"; Query query = session.createQuery(string); // query.setParameter(0, 2l); //hibernate查询是从0开始,与jdbc不同; // query.setParameter("cust_id", 1l); // Object uniqueResult = query.uniqueResult(); List<Customer> list = query.list(); System.out.println(list); transaction.commit(); HibernateUtil.closeSession(); }
拉轰的大蜗牛 2017-01-15
  • 打赏
  • 举报
回复
问题解决了, 做个结贴总结. 存在两个问题点 1. 主键生成策略 先前我使用<id name="userId" column="user_id" type="string"> <generator class="native"/> <!-- uuid生成唯一字符串 --> </id> java类中userId字段使用String类型 数据库t_user表中user_id使用varchar2类型 问题就出在这里, native主键生成策略, hibernate-oracle时, 会按照sequence策略生成主键, 此时hibernate生成的主键是Integer类型的. "一"懒加载出"多"的时候, hibernate会去拿Integer类型的字段去查t_order表, 这时候就出错了. 2.一对多List集合 list集合配置需要在order表增加一个index字段, 使用set集合就没这个要求. //User <hibernate-mapping package="com.hbt3.entity"> <class name="User" table="t_user" lazy="true"> <id name="userId" column="user_id" type="string"> <generator class="uuid"/> <!-- uuid生成唯一字符串 --> </id> <!-- <property name="userId" column="user_id"/> --> <property name="name" /> <property name="password"/> <property name="preference"/> <list name="orders" table="t_order" cascade="all" lazy="true" inverse="true"> <key column="user_id" /><!-- 一对多,多方的外键列 --><!-- 维护对方的外键 --> <index column="indexForList" type="long" /><!-- hibernate一对多list集合 特有的列, hibernate会维护orders的排序序号,从0开始 --> <one-to-many class="com.hbt3.entity.Order"/> </list> </class> </hibernate-mapping> //Order <hibernate-mapping package="com.hbt3.entity"> <class name="com.hbt3.entity.Order" table="t_order" lazy="true"> <id name="orderId" column="order_id" type="string"> <generator class="uuid" /> <!-- uuid生成唯一字符串 --> </id> <property name= "price" column="price"/> <property name= "createDatetime"/> <property name= "backup"/> <property name= "indexForList" type="long" /><!-- hibernate一对多list集合 特有的列 --> <many-to-one name="user" column="user_id" class="com.hbt3.entity.User" not-null="true" /> </class> </hibernate-mapping>
拉轰的大蜗牛 2017-01-14
  • 打赏
  • 举报
回复
自顶一下叼叼叼
拉轰的大蜗牛 2017-01-14
  • 打赏
  • 举报
回复
引用 1 楼 bcsflilong 的回复:
Caused by: java.sql.SQLException: 无法转换为内部表示

不能获取多的一方 是因为在获取多的一方的时候报错了
Order xml配置
<hibernate-mapping package="com.hbt3.entity">
<class name="Order" table="t_order" lazy="true">

<id name="order_id" column="order_id">
<generator class="native"/>
</id>

你的生成主键策咯是native 那么
private String order_id;//主键
应修改为private int order_id;//主键


我把数据库主键字段改成varchar2类型了,

public class User {
private String userId;

private String name;
private String password;
private String preference;
private List<Order> orders;
...略


public class Order {
private String orderId;

private BigDecimal price;
private Date createDatetime;
private User user;
private String backup;
...略

下面的insert()方法正常, query()方法还是那个错.
public static void query(){
Session session = HibernateUtil.getSession();// 获取session会话对象
session.beginTransaction();// 开始一个事务

String hql = " from User where name = ? ";
Query hqlQuery = session.createQuery(hql);// hql查询接口
hqlQuery.setParameter(0, "黄大侠");

List userList = hqlQuery.list();
Iterator iter = userList.iterator();
while(iter.hasNext()) {
User user=(User) iter.next();
System.out.println("user.name=" + user.getName());
user.getOrders();
// List<Order> orders = user.getOrders();
System.out.println("user.orders=" + user.getOrders().size());
}

if(session != null){
session.close();
}
}

public static void insert(){

Session session = HibernateUtil.getSession();// 获取session会话对象
Transaction txs = session.beginTransaction();// 开始一个事务

User user = new User();
user.setName("黄大侠");
user.setPassword("pwd");
user.setPreference("金毛犬");

List<Order> orders = new ArrayList<Order>();
Order order1 = new Order(new BigDecimal("12.10"), new Date(), user, "下单单");
Order order2 = new Order(new BigDecimal("66.10"), new Date(), user, "买了个狗");
orders.add(order1);
orders.add(order2);

user.setOrders(orders);

session.save(user); //先save一的一方
session.save(order1);//再save多的一方
session.save(order2);//再save多的一方

txs.commit();//hibernate默认 事务自动提交属性为false, 需要手动提交

if(session.isOpen() ||session.isConnected()) {
session.close();
}


}


bcsflilong 2017-01-09
  • 打赏
  • 举报
回复
Caused by: java.sql.SQLException: 无法转换为内部表示 不能获取多的一方 是因为在获取多的一方的时候报错了
Order xml配置
<hibernate-mapping package="com.hbt3.entity">
<class name="Order" table="t_order" lazy="true">

<id name="order_id" column="order_id">
<generator class="native"/>
</id>
你的生成主键策咯是native 那么
private String order_id;//主键
应修改为private int order_id;//主键

51,397

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧