2011-12-14 191 views
0

我想創建一個表,其中id是由字符串組成的。這是我所做的是以下一些例子和文檔:複合鍵休眠

 @Entity 
@Table(name = "media_locator") 
public class MediaLocator { 

    private List<MediaObject> mediaObjects; 
    private MediaLocatorPK primaryKey = new MediaLocatorPK(); 

// @Id 
// @GeneratedValue(strategy = GenerationType.AUTO) 
// @Column(name = "id", unique = true, nullable = false) 
// public int getId() { 
//  return id; 
// } 
// 
// public void setId(int id) { 
//   this.id = id; 
// } 

    @EmbeddedId 
    public MediaLocatorPK getPrimaryKey() { 
     return primaryKey; 
    } 

    public void setPrimaryKey(MediaLocatorPK primaryKey) { 
     this.primaryKey = primaryKey; 
    } 



// @Column(name = "location", length = 200) 
    public String getLocation() { 
     return primaryKey.getLocation(); 
    } 


    public void setLocation(String location) { 
     this.primaryKey.setLocation(location); 
    } 

// @Column(name = "description", length = 200, nullable = false) 
    public String getDescription() { 
     return primaryKey.getDescription(); 
    } 

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


// @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="mediaLocator")  
// public List<MediaObject> getMediaObjects() { 
//  return mediaObjects; 
// } 
// 
// public void setMediaObjects(List<MediaObject> mediaObjects) { 
//   mediaObjects = mediaObjects; 
// } 


    @ManyToMany(
      cascade={CascadeType.ALL}, 
      fetch=FetchType.LAZY) 
    @JoinTable(name = "media_object_location", 
      [email protected](name="mediaLocator_id"), 
      [email protected](name="mediaObject_id")) 
    public List<MediaObject> getMediaObjects() { 
     return mediaObjects; 
    } 

    public void setMediaObjects(List<MediaObject> mediaObjects) { 
     this.mediaObjects = mediaObjects; 
    } 


// @Column(name = "protocol", length = 200, nullable = false) 
    public String getProtocol() { 
     return primaryKey.getProtocol(); 
    } 

    public void setProtocol(String protocol) { 
     this.primaryKey.setProtocol(protocol); 
    } 
// @Column(name = "host", length = 200, nullable = false) 
    public String getHost() { 
     return primaryKey.getHost(); 
    } 

    public void setHost(String host) { 
     this.primaryKey.setHost(host); 
    } 
// @Column(name = "port", length = 200, nullable = false) 
    public String getPort() { 
     return primaryKey.getPort(); 
    } 

    public void setPort(String port) { 
     this.primaryKey.setPort(port); 
    } 
// @Column(name = "path", length = 200, nullable = false) 
    public String getPath() { 
     return primaryKey.getPath(); 
    } 

    public void setPath(String path) { 
     this.primaryKey.setPath(path); 
    } 

@Embeddable class MediaLocatorPK implements Serializable 
{ 
    private String location; 
    private String description; 
    private String protocol; 
    private String host; 
    private String port; 
    private String path; 

    public String getLocation() { 
     return location; 
    } 
    public void setLocation(String location) { 
     this.location = location; 
    } 
    public String getDescription() { 
     return description; 
    } 
    public void setDescription(String description) { 
     this.description = description; 
    } 
    public String getProtocol() { 
     return protocol; 
    } 
    public void setProtocol(String protocol) { 
     this.protocol = protocol; 
    } 
    public String getHost() { 
     return host; 
    } 
    public void setHost(String host) { 
     this.host = host; 
    } 
    public String getPort() { 
     return port; 
    } 
    public void setPort(String port) { 
     this.port = port; 
    } 
    public String getPath() { 
     return path; 
    } 
    public void setPath(String path) { 
     this.path = path; 
    } 


} 

之前,我不得不產生的ID,汽車,每個屬性附加傷害表中,@Column(name = "location", length = 200)有科拉姆,例如。

這樣,我不能存儲數據,由於與其他物體

關係referencies
Caused by: org.hibernate.AnnotationException: A Foreign key refering com.app.MediaLocator from com.app.MediaObject has the wrong number of column. should be 6 
    at org.hibernate.cfg.annotations.TableBinder.bindFk(TableBinder.java:429) 
    at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.java:1443) 
    at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1262) 
    at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:693) 
    at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:628) 
    at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:65) 
    at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1686) 
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1393) 
    at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1345) 
    at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:717) 
    at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1469) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1409) 

這種特殊的關係是:

@ManyToMany(
      cascade={CascadeType.ALL}, 
      fetch=FetchType.LAZY) 
    @JoinTable(name = "media_object_location", 
      [email protected](name="mediaLocator_id"), 
      [email protected](name="mediaObject_id")) 
    public List<MediaObject> getMediaObjects() { 
     return mediaObjects; 
    } 

    public void setMediaObjects(List<MediaObject> mediaObjects) { 
     this.mediaObjects = mediaObjects; 
    } 

而且從的mediaObject方:

@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY, mappedBy = "mediaObjects") 
    public List<MediaLocator> getMediaLocators() { 
     return mediaLocators; 
    } 

    public void setMediaLocators(List<MediaLocator> mediaLocators) { 
     this.mediaLocators = mediaLocators; 
    } 

我做錯了什麼?

在此先感謝

+0

你有沒有例外? – mprabhat 2011-12-14 18:31:59

+0

剛剛編輯我的問題,我意識到我沒有足夠的信息 – 2011-12-14 18:32:58

回答

2

一旦你移動性能,你需要從主類中刪除它們嵌入類,屆時會有一個嵌入式類的引用,所以在你的榜樣,你需要刪除所有屬性,如MediaLocator類的位置。

什麼是財產id在你的MediaLocator做?由於在類中沒有特定的列註解,因此hibernate會嘗試將每個屬性映射到表列,如果屬性和表列的命名都相同,那麼它將在該映射中成功。

如果你不需要id然後刪除它或將其標記爲@Transient

這段代碼將重現你所得到的同樣的錯誤。

學生班級

package com.mumz.test.jpa.embedded.manytomany; 

import java.util.Set; 

import javax.persistence.CascadeType; 
import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.JoinTable; 
import javax.persistence.ManyToMany; 
import javax.persistence.Table; 

@Entity 
@Table(name="STUDENT") 
public class StudentMTM { 

    private StudentMTMPK studentPK = null; 
    private Set<Address>  address  = null; 

    public StudentMTM(StudentMTMPK studentPK, Set<Address> address) { 
     super(); 
     this.studentPK = studentPK; 
     this.address = address; 
    } 

    /** 
    * @return the id 
    */ 
    public Integer getId() { 
     return studentPK.getId(); 
    } 

    /** 
    * @param id the id to set 
    */ 
    public void setId(Integer id) { 
     studentPK.setId(id); 
    } 

    /** 
    * @return the name 
    */ 
    public String getName() { 
     return studentPK.getName(); 
    } 

    /** 
    * @param name the name to set 
    */ 
    public void setName(String name) { 
     studentPK.setName(name); 
    } 
    /** 
    * @param studentPK 
    *   the studentPK to set 
    */ 
    public void setStudentPK(StudentMTMPK studentPK) { 
     this.studentPK = studentPK; 
    } 

    /** 
    * @param address 
    *   the address to set 
    */ 
    public void setAddress(Set<Address> address) { 
     this.address = address; 
    } 

    /** 
    * @return the address 
    */ 
    @ManyToMany(cascade = CascadeType.ALL) 
    @JoinTable(name = "STUDENT_ADDRESS", joinColumns = 
     { 
      @JoinColumn(name = "STUDENT_ID") 
     }, inverseJoinColumns = 
     { 
      @JoinColumn(name = "ADDRESS_ID") 
     }) 
    public Set<Address> getAddress() { 
     return address; 
    } 

    /** 
    * @return the studentPK 
    */ 
    @Id 
    public StudentMTMPK getStudentPK() { 
     return studentPK; 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see java.lang.Object#hashCode() 
    */ 
    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((studentPK == null) ? 0 : studentPK.hashCode()); 
     result = prime * result + ((address == null) ? 0 : address.hashCode()); 
     return result; 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see java.lang.Object#equals(java.lang.Object) 
    */ 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj == null) { 
      return false; 
     } 
     if (!(obj instanceof StudentMTM)) { 
      return false; 
     } 
     StudentMTM other = (StudentMTM) obj; 
     if (studentPK == null) { 
      if (other.studentPK != null) { 
       return false; 
      } 
     } else if (!studentPK.equals(other.studentPK)) { 
      return false; 
     } 
     if (address == null) { 
      if (other.address != null) { 
       return false; 
      } 
     } else if (!address.equals(other.address)) { 
      return false; 
     } 
     return true; 
    } 
} 

學生PK類:

package com.mumz.test.jpa.embedded.manytomany; 

import java.io.Serializable; 

import javax.persistence.Column; 
import javax.persistence.Embeddable; 

@Embeddable 
public class StudentMTMPK implements Serializable{ 
    /** 
    * 
    */ 
    private static final long serialVersionUID = 3686950547855931594L; 
    private Integer id = null; 
    private String name = null; 

    public StudentMTMPK(Integer id, String name) { 
     this.id = id; 
     this.name = name; 
    } 

    /** 
    * @return the id 
    */ 
    @Column(name="STUDENT_ID") 
    public Integer getId() { 
     return id; 
    } 

    /** 
    * @param id the id to set 
    */ 
    public void setId(Integer id) { 
     this.id = id; 
    } 

    /** 
    * @return the name 
    */ 
    @Column(name="STUDENT_NAME") 
    public String getName() { 
     return name; 
    } 

    /** 
    * @param name the name to set 
    */ 
    public void setName(String name) { 
     this.name = name; 
    } 

    /* (non-Javadoc) 
    * @see java.lang.Object#hashCode() 
    */ 
    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((id == null) ? 0 : id.hashCode()); 
     result = prime * result + ((name == null) ? 0 : name.hashCode()); 
     return result; 
    } 

    /* (non-Javadoc) 
    * @see java.lang.Object#equals(java.lang.Object) 
    */ 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj == null) { 
      return false; 
     } 
     if (!(obj instanceof StudentMTMPK)) { 
      return false; 
     } 
     StudentMTMPK other = (StudentMTMPK) obj; 
     if (id == null) { 
      if (other.id != null) { 
       return false; 
      } 
     } else if (!id.equals(other.id)) { 
      return false; 
     } 
     if (name == null) { 
      if (other.name != null) { 
       return false; 
      } 
     } else if (!name.equals(other.name)) { 
      return false; 
     } 
     return true; 
    } 
} 

地址類

package com.mumz.test.jpa.embedded.manytomany; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.Table; 

@Entity 
@Table(name="ADDRESS") 
public class Address { 
    private Integer id = null; 
    private String addressDetails = null; 

    /** 
    * @return the id 
    */ 
    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(name="ADDRESS_ID") 
    public Integer getId() { 
     return id; 
    } 

    /** 
    * @param id the id to set 
    */ 
    public void setId(Integer id) { 
     this.id = id; 
    } 

    /** 
    * @return the addressDetails 
    */ 
    @Column(name="ADDRESS_DETAILS") 
    public String getAddressDetails() { 
     return addressDetails; 
    } 

    /** 
    * @param addressDetails the addressDetails to set 
    */ 
    public void setAddressDetails(String addressDetails) { 
     this.addressDetails = addressDetails; 
    } 

    /* (non-Javadoc) 
    * @see java.lang.Object#hashCode() 
    */ 
    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((addressDetails == null) ? 0 : addressDetails.hashCode()); 
     result = prime * result + ((id == null) ? 0 : id.hashCode()); 
     return result; 
    } 

    /* (non-Javadoc) 
    * @see java.lang.Object#equals(java.lang.Object) 
    */ 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj == null) { 
      return false; 
     } 
     if (!(obj instanceof Address)) { 
      return false; 
     } 
     Address other = (Address) obj; 
     if (addressDetails == null) { 
      if (other.addressDetails != null) { 
       return false; 
      } 
     } else if (!addressDetails.equals(other.addressDetails)) { 
      return false; 
     } 
     if (id == null) { 
      if (other.id != null) { 
       return false; 
      } 
     } else if (!id.equals(other.id)) { 
      return false; 
     } 
     return true; 
    } 
} 

如果運行這段代碼並嘗試保存地址的實例,你會得到

Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: myJPAService] Unable to configure EntityManagerFactory 
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:378) 
    at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:56) 
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:63) 
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:47) 
    at com.mumz.test.jpa.embedded.manytomany.EmbeddableTestMainApp.main(EmbeddableTestMainApp.java:9) 
Caused by: org.hibernate.AnnotationException: A Foreign key refering com.mumz.test.jpa.embedded.manytomany.StudentMTM from com.mumz.test.jpa.embedded.manytomany.Address has the wrong number of column. should be 2 
    at org.hibernate.cfg.annotations.TableBinder.bindFk(TableBinder.java:429) 
    at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.java:1460) 
    at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1279) 
    at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:710) 
    at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:645) 
    at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:65) 
    at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1716) 
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1423) 
    at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1375) 
    at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1519) 
    at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:193) 
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1100) 
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:282) 
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:366) 

我的manytomany在StudentMTM已打破。

現在這一塊會工作,因爲它應該是:

學生班級

package com.mumz.test.jpa.embedded.manytomany; 

import java.util.Set; 

import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.JoinTable; 
import javax.persistence.ManyToMany; 
import javax.persistence.Table; 

@Entity 
@Table(name="STUDENT") 
public class StudentMTM { 

    private StudentMTMPK studentPK = null; 
    private Integer id = null; 
    private Set<Address>  address  = null; 

    public StudentMTM(StudentMTMPK studentPK, Set<Address> address) { 
     super(); 
     this.studentPK = studentPK; 
     this.address = address; 
    } 

    /** 
    * @return the id 
    */ 
    @Column(name="STUDENT_ID") 
    public Integer getId() { 
     return id; 
    } 

    /** 
    * @param id the id to set 
    */ 
    public void setId(Integer id) { 
     this.id = id; 
    } 

    /** 
    * @return the name 
    */ 
    public String getName() { 
     return studentPK.getName(); 
    } 

    /** 
    * @param name the name to set 
    */ 
    public void setName(String name) { 
     studentPK.setName(name); 
    } 
    /** 
    * @param studentPK 
    *   the studentPK to set 
    */ 
    public void setStudentPK(StudentMTMPK studentPK) { 
     this.studentPK = studentPK; 
    } 

    /** 
    * @param address 
    *   the address to set 
    */ 
    public void setAddress(Set<Address> address) { 
     this.address = address; 
    } 

    /** 
    * @return the address 
    */ 
    @ManyToMany(cascade = CascadeType.ALL) 
    @JoinTable(name = "STUDENT_ADDRESS", joinColumns = 
     { 
      @JoinColumn(name = "STUDENT_ID") 
     }, inverseJoinColumns = 
     { 
      @JoinColumn(name = "ADDRESS_ID") 
     }) 
    public Set<Address> getAddress() { 
     return address; 
    } 

    /** 
    * @return the studentPK 
    */ 
    @Id 
    public StudentMTMPK getStudentPK() { 
     return studentPK; 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see java.lang.Object#hashCode() 
    */ 
    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((studentPK == null) ? 0 : studentPK.hashCode()); 
     result = prime * result + ((address == null) ? 0 : address.hashCode()); 
     return result; 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see java.lang.Object#equals(java.lang.Object) 
    */ 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj == null) { 
      return false; 
     } 
     if (!(obj instanceof StudentMTM)) { 
      return false; 
     } 
     StudentMTM other = (StudentMTM) obj; 
     if (studentPK == null) { 
      if (other.studentPK != null) { 
       return false; 
      } 
     } else if (!studentPK.equals(other.studentPK)) { 
      return false; 
     } 
     if (address == null) { 
      if (other.address != null) { 
       return false; 
      } 
     } else if (!address.equals(other.address)) { 
      return false; 
     } 
     return true; 
    } 
} 

學生PK

package com.mumz.test.jpa.embedded.manytomany; 

import java.io.Serializable; 

import javax.persistence.Column; 
import javax.persistence.Embeddable; 

@Embeddable 
public class StudentMTMPK implements Serializable{ 
    /** 
    * 
    */ 
    private static final long serialVersionUID = 3686950547855931594L; 
    private String name = null; 

    public StudentMTMPK(String name) { 
     this.name = name; 
    } 

    /** 
    * @return the name 
    */ 
    @Column(name="STUDENT_NAME") 
    public String getName() { 
     return name; 
    } 

    /** 
    * @param name the name to set 
    */ 
    public void setName(String name) { 
     this.name = name; 
    } 

    /* (non-Javadoc) 
    * @see java.lang.Object#hashCode() 
    */ 
    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((name == null) ? 0 : name.hashCode()); 
     return result; 
    } 

    /* (non-Javadoc) 
    * @see java.lang.Object#equals(java.lang.Object) 
    */ 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj == null) { 
      return false; 
     } 
     if (!(obj instanceof StudentMTMPK)) { 
      return false; 
     } 
     StudentMTMPK other = (StudentMTMPK) obj; 
     if (name == null) { 
      if (other.name != null) { 
       return false; 
      } 
     } else if (!name.equals(other.name)) { 
      return false; 
     } 
     return true; 
    } 
} 

地址類 - 從第一個版本沒有變化。

在第二個版本中,JoinColumn是Student的一部分,映射知道它映射到的位置。