2014-09-21 206 views
0

我有一个Hibernate项目中的以下文件:一对多双向映射

Customer.java,Request.java,Client.java和hibernate.cfg.xml如下:

Customer.java

 @Entity 
     @Table(name="customers") 
     public class Customer { 

      @Id 
      @Column(name="cid") 
      @GeneratedValue(strategy=GenerationType.AUTO) 
     private int cid; 
      @Column(name="name") 
     private String name; 
      @Column(name="phone") 
     private long phone; 

      @OneToMany(mappedBy="customer") 
     private Set<Request> requests; 


     public Customer() { 
      super(); 
     } 
     public Customer(String name, long phone) { 
      super(); 
      this.name = name; 
      this.phone = phone; 
     } 
     public int getCid() { 
      return cid; 
     } 
     public void setCid(int cid) { 
      this.cid = cid; 
     } 
     public String getName() { 
      return name; 
     } 
     public void setName(String name) { 
      this.name = name; 
     } 
     public long getPhone() { 
      return phone; 
     } 
     public void setPhone(long phone) { 
      this.phone = phone; 
     } 
     public Set<Request> getRequests() { 
      return requests; 
     } 
     public void setRequests(Set<Request> requests) { 
      this.requests = requests; 
     } 
     @Override 
     public String toString() { 
      return "Customer [cid=" + cid + ", name=" + name + ", phone=" + phone 
        +"]"; 
     } 
     } 

Request.java

 @Entity 
     @Table(name="requests") 
     public class Request { 

      @Id 
      @Column(name="reqid") 
      @GeneratedValue(strategy=GenerationType.AUTO) 
     private int reqId; 

      @Column(name="reqdate") 
     private String reqDate; 

      @Column(name="description") 
     private String description; 
      @Column(name="status") 
     private String status; 

     @ManyToOne 
     @JoinColumn(name="cid",referencedColumnName="cid") 
     private Customer customer; 

     public Request() { 
      super(); 
     } 

     public Request(String reqDate, String description, String status) { 
      super(); 
      this.reqDate = reqDate; 
      this.description = description; 
      this.status = status; 
     } 

     public int getReqId() { 
      return reqId; 
     } 

     public void setReqId(int reqId) { 
      this.reqId = reqId; 
     } 

     public String getReqDate() { 
      return reqDate; 
     } 

     public void setReqDate(String reqDate) { 
      this.reqDate = reqDate; 
     } 

     public String getDescription() { 
      return description; 
     } 

     public void setDescription(String description) { 
      this.description = description; 
     } 

     public String getStatus() { 
      return status; 
     } 

     public void setStatus(String status) { 
      this.status = status; 
     } 

     public Customer getCustomer() { 
      return customer; 
     } 

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

     @Override 
     public String toString() { 
      return "Request [reqId=" + reqId + ", reqDate=" + reqDate 
        + ", description=" + description + ", status=" + status 
        + ", customer=" + customer + "]"; 
     } 
     } 

的hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?> 
    <!DOCTYPE hibernate-configuration PUBLIC 
       "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
       "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 

    <hibernate-configuration> 
     <session-factory> 
      <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 
      <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/ahamdb</property> 
      <property name="hibernate.connection.username">root</property> 
      <property name="hibernate.connection.password">root</property> 
      <property name="dialect">org.hibernate.dialect.MySQLDialect</property> 
      <property name="show_sql">true</property> 
    <property name="hibernate.hbm2ddl.auto">create</property>  

      <mapping class="com.kar.hibernate.Customer" /> 
    <mapping class="com.kar.hibernate.Request" /> 
     </session-factory> 
    </hibernate-configuration> 

Client.java

 public class Client{ 
     public static void main(String[] args) { 
      Transaction tx=null; 
      try 
      { 
      SessionFactory sessionFactory=AHibernateUtil.getSessionFactory(); 
      Session session=sessionFactory.openSession(); 
      tx=session.beginTransaction(); 

      Customer cust=new Customer("bnuj",1111); 
      session.save(cust); 

     Request req1=new Request("4-1-14", "desc1", "active"); 
      session.save(req1); 

      Request req2=new Request("4-2-14", "desc2", "unactive"); 
      session.save(req2); 

      Set<Request> requests=new HashSet<Request>(); 
      requests.add(req1); 
      requests.add(req2); 
      cust.setRequests(requests); 

     tx.commit(); 
     session.close(); 
      } 
      catch(Exception e) 
      { 
       e.printStackTrace(); 
       if(tx!=null) 
       tx.rollback(); 
      } 
     } 
     } 

的问题是,当我运行的客户端代码,它是生产的结果:

Hibernate: insert into customers (name, phone) values (?, ?) 
    Hibernate: insert into requests (cid, description, reqdate, status) values (?, ?, ?, ?) 
    Hibernate: insert into requests (cid, description, reqdate, status) values (?, ?, ?, ?) 

它不更新外键列在请求表中,我不明白为什么它是如此 任何人都可以帮忙吗?

我想知道我是否正确或不正确,如果没有,是否有人可以发布正确的解决方案?

回答

1

问题出现在逆映射中。如果我们把这个声明:@OneToMany(mappedBy="customer"),即mappedBy,我们指示休眠:

关系的另一端会关心持久性。

它将,以及它会,如果另一端 - 在请求,会知道这件事 - 将有客户正确地分配。因此,这应该解决这个问题:

... 
cust.setRequests(requests); 
req1.setCustomer(cust); 
req2.setCustomer(cust); 

休眠现在有足够的信息来正确地插入/更新的关系

这个读数也应该有所帮助:

+0

嗨,感谢您的回复,它工作无线th:req1.setCustomer(cust); req2.setCustomer(cust);但我想知道在currrent实现中我应该做些什么来使它适用于:cust.setRequests(requests);无论如何,感谢您的帮助 – 2014-09-22 17:35:04

+0

我强烈建议:使用我在答案中给出的方法。这将生成最有效的SQL语句。任何其他映射都会导致更复杂的处理1)集合项的一个特殊插入2)下一次更新与父项关联。此外,集合的更新将更加复杂。事实上 - 你的映射是最好的。只需调整代码中的几行即可设置关系的两侧。这就是......真的。享受Hiberante;) – 2014-09-22 18:05:38

+0

只是调整代码中的几行来设置关系的两个方面。你能告诉我这个代码: – 2014-09-22 19:04:08