Hibernate 的一些问题

woainilxt 2009-03-09 10:24:07
问几个问题:1.inverse属性,指关系和对象的级联怎么理解?一对多的时候,就仅仅是影响效率,少执行几条SQL么?
“set的inverse属性决定是否把对set的改动反映到数据库中去。
inverse=false————反映;inverse=true————不反映 inverse属性默认为false"
怎么理解啊?

2.单向/双向的一对多,如果不借助数据库中多表的外键on delete 設為 cascade,能实现级联删除或者更新么?
3.单向多对一中(一个房间住多个人),當你把某一個 user給坎掉時,他的room也會被刪除,在被刪的同時,所有與room相關的user也會一同被刪除,
这样的功能怎么实现?

4.在双向一对多中配置的时候,都不配(或者其中一方不配)cascode属性,会影响什么?
5.<set name="raiseCollectAdviceSet"
cascade="all"
order-by=" id asc "
inverse="true"
where="check_Status=3"
lazy="true">
<key column="WTOINFO_ID"/>
<one-to-many class="com.taiji.bzw.hibernate.model.AppWtotbtCheck"/>
</set>
随便问下,order-by=" id asc ",where="check_Status=3" set中还能加条件?


分不多(想把分都发了,系统不让...),但很有诚意,请通俗的回答(高深了,现在领悟不了),非常感谢!!
PS:不是我不看书,可是书上讲的,看的有点迷糊 。。。。。。。。。。
...全文
432 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
woainilxt 2009-03-12
  • 打赏
  • 举报
回复
迷糊!
zhangbo6791644 2009-03-12
  • 打赏
  • 举报
回复
我来解释一下,21楼出现的情况,在hibernate中对应生成数据库的表转换成对象,实际上应用了javabean的原理,必须是私有的,这是规则,记住就可以了
woainilxt 2009-03-11
  • 打赏
  • 举报
回复
不是吧,大大
tzb08 2009-03-11
  • 打赏
  • 举报
回复
恩 不错的东东
Landor2004 2009-03-11
  • 打赏
  • 举报
回复
这个可能要去看hibernate的源码
woainilxt 2009-03-11
  • 打赏
  • 举报
回复
<set name="orderses" inverse="true" cascade="all">
<key>
<column name="customer_id" />
</key>
<one-to-many class="pojo.Orders" />
</set>



<many-to-one name="customer" class="pojo.Customer" fetch="select" cascade="all">
<column name="customer_id" />
</many-to-one>



public class Test {
public static void main(String[] args) {
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
Customer customer = (Customer) session.load(Customer.class,
new Integer(39));//数据库存在的一个对象
session.delete(customer);
tx.commit();
session.close();
}

}



把setOrderses设置为private

就可以达到级联删除的目的,


private void setOrderses(Set orderses) {
this.orderses = orderses;
}
关键在这,请解惑...我测试了,我这种写法必须private,为什么啊?
Landor2004 2009-03-11
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 woainilxt 的回复:]
private void setOrderses(Set orderses) {
this.orderses = orderses;
}
??????????
[/Quote]
我记得不设置成privlate也行,呵呵
woainilxt 2009-03-11
  • 打赏
  • 举报
回复
private void setOrderses(Set orderses) {
this.orderses = orderses;
}
??????????
AgileGuest 2009-03-10
  • 打赏
  • 举报
回复
不懂 帮顶!
woainilxt 2009-03-10
  • 打赏
  • 举报
回复
测试类:

public class Test {
public static void main(String[] args) {
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
Customer customer = new Customer();
Orders order1 = new Orders();
Orders order2 = new Orders();
Orders order3 = new Orders();
customer.setPhone("bbb");
customer.setUsername("bbb");
customer.setBank("bbb");
order1.setOrderId("5555");
order1.setMoney(new Double(100));
order1.setCustomer(customer);
order2.setOrderId("5555");
order2.setMoney(new Double(200));
order2.setCustomer(customer);
order3.setOrderId("5555");
order3.setMoney(new Double(300));
order3.setCustomer(customer);
session.save(order1);
session.save(order2);
session.save(order3);
tx.commit();
session.close();
}

没问题,而

public class Test {
public static void main(String[] args) {
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
Customer customer = new Customer();
Orders order1 = new Orders();
Orders order2 = new Orders();
Orders order3 = new Orders();
customer.setPhone("bbb");
customer.setUsername("bbb");
customer.setBank("bbb");
order1.setOrderId("5555");
order1.setMoney(new Double(100));
order1.setCustomer(customer);
order2.setOrderId("5555");
order2.setMoney(new Double(200));
order2.setCustomer(customer);
order3.setOrderId("5555");
order3.setMoney(new Double(300));
order3.setCustomer(customer);
customer.addOrders(order1);
customer.addOrders(order2);
customer.addOrders(order3);
session.save(customer);
tx.commit();
session.close();
}

也没问题,如果注释掉
order1.setCustomer(customer);
order2.setCustomer(customer);
order3.setCustomer(customer);
则多表外键为NULL,这就是inverse的问题么?
我想明白的是inverse,cascode在test代码执行的时候,他们各自起了什么作用,在什么时候?谢谢!
rascalboy520 2009-03-10
  • 打赏
  • 举报
回复
mark一下,
woainilxt 2009-03-10
  • 打赏
  • 举报
回复
写了个例子,做了些测试
顾客类
package pojo;

import java.util.HashSet;
import java.util.Set;

/**
* Customer entity.
*
* @author MyEclipse Persistence Tools
*/

public class Customer implements java.io.Serializable {

// Fields

private Integer id;
private String username;
private String bank;
private String phone;
private Set orderses = new HashSet(0);

// Constructors

/** default constructor */
public Customer() {
}

/** full constructor */
public Customer(String username, String bank, String phone, Set orderses) {
this.username = username;
this.bank = bank;
this.phone = phone;
this.orderses = orderses;
}

// Property accessors

public Integer getId() {
return this.id;
}

public void setId(Integer id) {
this.id = id;
}

public String getUsername() {
return this.username;
}

public void setUsername(String username) {
this.username = username;
}

public String getBank() {
return this.bank;
}

public void setBank(String bank) {
this.bank = bank;
}

public String getPhone() {
return this.phone;
}

public void setPhone(String phone) {
this.phone = phone;
}

public Set getOrderses() {
return this.orderses;
}

public void setOrderses(Set orderses) {
this.orderses = orderses;
}
public void addOrders(Orders orders){
orderses.add(orders);
}

}

订单类

package pojo;

/**
* Orders entity.
*
* @author MyEclipse Persistence Tools
*/

public class Orders implements java.io.Serializable {

// Fields

private Integer id;
private Customer customer;
private Double money;
private String orderId;

// Constructors

/** default constructor */
public Orders() {
}

/** full constructor */
public Orders(Customer customer, Double money, String orderId) {
this.customer = customer;
this.money = money;
this.orderId = orderId;
}

// Property accessors

public Integer getId() {
return this.id;
}

public void setId(Integer id) {
this.id = id;
}

public Customer getCustomer() {
return this.customer;
}

public void setCustomer(Customer customer) {
this.customer = customer;
}

public Double getMoney() {
return this.money;
}

public void setMoney(Double money) {
this.money = money;
}

public String getOrderId() {
return this.orderId;
}

public void setOrderId(String orderId) {
this.orderId = orderId;
}

}


<hibernate-mapping>
<class name="pojo.Customer" table="customer" catalog="student">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native" />
</id>
<property name="username" type="java.lang.String">
<column name="username" length="10" />
</property>
<property name="bank" type="java.lang.String">
<column name="bank" length="20" />
</property>
<property name="phone" type="java.lang.String">
<column name="phone" length="10" />
</property>
<set name="orderses" inverse="true" cascade="all">
<key>
<column name="customer_id" />
</key>
<one-to-many class="pojo.Orders" />
</set>
</class>
</hibernate-mapping>




<hibernate-mapping>
<class name="pojo.Orders" table="orders" catalog="student">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native" />
</id>
<many-to-one name="customer" class="pojo.Customer" fetch="select" cascade="all">
<column name="customer_id" />
</many-to-one>
<property name="money" type="java.lang.Double">
<column name="money" precision="22" scale="0" />
</property>
<property name="orderId" type="java.lang.String">
<column name="orderId" length="20" />
</property>
</class>
</hibernate-mapping>
woainilxt 2009-03-10
  • 打赏
  • 举报
回复
非常感谢Landor2004,java2000-net
1.再看过http://acme1921209.javaeye.com/blog/67689后,对inverse认识更深刻了,维护关系,在一对多中是不是就成负责外键修改的?(能这么理解么)
2.http://hi.baidu.com/landor2004/blog/item/d7bc760193d995031d95839a.html ,这个没看明白 。hibernate的cascode和数据库的cascode什么关系啊?
3.我的意思是多对一单向,再依靠数据库本身存在的外键on delete 設為 cascade,能不能实现我要的功能?
4.我的意思是一对多中,“一”边inverse=“TRUE”,而两边的cascode都不设,会出现什么?为什么?
5.这两个地方似乎只能在一个地方加?我想知道这两个属性是干什么的啊?有什么用?
麻烦了,追加100,请大家补充下
AgileGuest 2009-03-10
  • 打赏
  • 举报
回复
恩 不错 学习了
woainilxt 2009-03-10
  • 打赏
  • 举报
回复
我的第五个问题,谁来说说,那两个属性干什么的啊
另外,关于级联删除

<set name="orderses" inverse="true" cascade="all">
<key>
<column name="customer_id" />
</key>
<one-to-many class="pojo.Orders" />
</set>



<many-to-one name="customer" class="pojo.Customer" fetch="select" cascade="all">
<column name="customer_id" />
</many-to-one>



public class Test {
public static void main(String[] args) {
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
Customer customer = (Customer) session.load(Customer.class,
new Integer(39));//数据库存在的一个对象
session.delete(customer);
tx.commit();
session.close();
}

}

把setOrderses设置为private

就可以达到级联删除的目的,


private void setOrderses(Set orderses) {
this.orderses = orderses;
}
关键在这,请解惑...
AgileGuest 2009-03-10
  • 打赏
  • 举报
回复
还是不是很清楚啊!
woainilxt 2009-03-10
  • 打赏
  • 举报
回复
哦,发现问题了,该了就对了,谢谢Landor2004
woainilxt 2009-03-10
  • 打赏
  • 举报
回复
session.save(order1);
session.save(order2);
session.save(order3);
是注释掉的
woainilxt 2009-03-10
  • 打赏
  • 举报
回复

public class Test {
public static void main(String[] args) {
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
Customer customer = new Customer();
Orders order1 = new Orders();
Orders order2 = new Orders();
Orders order3 = new Orders();
customer.setPhone("bbb");
customer.setUsername("bbb");
customer.setBank("bbb");
order1.setOrderId("5555");
order1.setMoney(new Double(100));
// order1.setCustomer(customer);
order2.setOrderId("5555");
order2.setMoney(new Double(200));
// order2.setCustomer(customer);
order3.setOrderId("5555");
order3.setMoney(new Double(300));
// order3.setCustomer(customer);
customer.addOrders(order1);
customer.addOrders(order2);
customer.addOrders(order3);
session.save(customer);
session.save(order1);
session.save(order2);
session.save(order3);
tx.commit();
session.close();
}

}

Exception in thread "main" org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: pojo.Orders
at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:219)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:397)
at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:78)
at org.hibernate.persister.collection.AbstractCollectionPersister.writeElement(AbstractCollectionPersister.java:755)
at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1143)
at org.hibernate.action.CollectionRecreateAction.execute(CollectionRecreateAction.java:39)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:171)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at dao.Test.main(Test.java:38)
Landor2004 2009-03-10
  • 打赏
  • 举报
回复
inverse是是否维护关系的意思,cascade是是否级联操作,如果cascade设置成none的话,那么设置inverse有时会出现错误
比如插入many的时候,没有级联one,那么one在表中是空的,那就会报错,所以cascade最好设置成all

cascade有几个属性,楼主自己可以查查。他其实就模拟实现数据库中的级联,但是有个不同就是当进行删除的时候,如果设置成all,那么删除one表记录,其子表记录不会删除,而是把关联字段设置成null,这样会出现孤立的子表记录,所以要用到上面的帖子来完成彻底删除操作。
one-to-many,one中inverse可以设置,many中的inverse不可以设置,钉死为false(维护关系)

如果one中inverse="true"那么关系由many来维护,所以在many中一定要设置one的属性,比如setCustomer,否则关联字段就会使空置

如果one中inverse="false"那么关系既由one来维护,又有many来维护,这样会生成多余的语句,因为在many插入条记录的时候,就会触发one断的update子表的sql语句,所以即使不设置many端的setCustomer结果也正确,因为关联主键是通过one端的setXxxs来维护的。通常不建议这种方式,因为他会出现冗余的sql语句
加载更多回复(4)

67,512

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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