问几个问题: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:不是我不看书,可是书上讲的,看的有点迷糊 。

解决方案 »

  1.   

    1 inverse是是否维护关联关系的意思,true表示不维护,false表示维护。不好说明白,给你个地址自己看一下
     http://acme1921209.javaeye.com/blog/676892 hibernate的cascade就是干这个用的,里面有一些值,比如all update delete ,这里的操作不是删除关联数据,而是把关联的字段摄政成空,如果想删除的话,得用all-delete-orphan,不能简单的使用,看下这里
    http://hi.baidu.com/landor2004/blog/item/d7bc760193d995031d95839a.html3 这就不是单项的了,这是双向的,然后设置cascade4 invserse是维护关系的意思,cascade是是否联机,如果cascade设置成none了,而inverse设置成false,当进行插入one表的时候,会出现错误。5 我曾经测试过,这两个地方似乎只能在一个地方加,呵呵
      

  2.   

    请 Landor2004 来解答吧。我就不重复了。
      

  3.   

    非常感谢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,请大家补充下
      

  4.   

    写了个例子,做了些测试
    顾客类
    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>
      

  5.   

    测试类: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代码执行的时候,他们各自起了什么作用,在什么时候?谢谢!
      

  6.   

    inverse是是否维护关系的意思,cascade是是否级联操作,如果cascade设置成none的话,那么设置inverse有时会出现错误
    比如插入many的时候,没有级联one,那么one在表中是空的,那就会报错,所以cascade最好设置成allcascade有几个属性,楼主自己可以查查。他其实就模拟实现数据库中的级联,但是有个不同就是当进行删除的时候,如果设置成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语句
      

  7.   


    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)
      

  8.   

            session.save(order1);
            session.save(order2);
            session.save(order3);
    是注释掉的
      

  9.   

    哦,发现问题了,该了就对了,谢谢Landor2004
      

  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;
          }
    关键在这,请解惑...
      

  11.   

            private void setOrderses(Set orderses) { 
    this.orderses = orderses; 
          }
    ??????????
      

  12.   

    我记得不设置成privlate也行,呵呵
      

  13.   

            <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,为什么啊?
      

  14.   

    这个可能要去看hibernate的源码
      

  15.   

    我来解释一下,21楼出现的情况,在hibernate中对应生成数据库的表转换成对象,实际上应用了javabean的原理,必须是私有的,这是规则,记住就可以了