2011-12-14 2 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를 자동 생성했고, 각 atribute는 예를 들어, 테이블, @Column(name = "location", length = 200)에 콜 럼을했다.

@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; 
    } 

그리고 미디어 오브젝트의 측면에서 : 인해 다른 개체

과의 관계에서 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.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

+0

방금 ​​제 질문을 편집했는데, 충분한 정보가 없다는 것을 깨달았습니다 –

+0

좋은 디자인 (단일 ID 열, 자동 생성 됨)에서 나쁜 열 (모든 열이 복합 기본 키를 형성하는 테이블)로갔습니다. 왜 그것을하고 있습니까? MediaLocator 객체를 참조하는 모든 엔티티는 자체 테이블에 6 개의 열을 복제해야합니다. 그리고 MediaLocator에서 값을 변경할 수 없습니다. 그렇게하지 마! –

답변

2

은 임베디드 클래스의 하나의 참조가 될 것입니다 MediaLocator 클래스의 위치와 같은 속성

MediaLocator에서 재산 id은 무엇입니까? 클래스에 특별한 컬럼 주석이 없기 때문에, 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; 
    } 
} 

당신이 코드 조각을 실행하고 것 주소의 인스턴스를 저장하려고하면 get

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) 

StudentMTM에 내 manytomany가 깨졌습니다. 그것이 있어야로

지금이 작품은 작동하지 않습니다 :

학생 클래스를

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의 일부이며 매핑은 매핑 할 위치를 알고 있습니다.

+0

나는 모든 속성이 결합 된 ID를 원합니다. 방금 내 코드의 변경 사항으로 내 질문을 편집했습니다. 덕분에 –

+0

귀하의 협회 manytomany가 깨졌습니다, 당신의 조인 열이 mediaLocator_id 그래서 당신의 미디어 로케이터에 어떤 열을 참조 할 것입니까? 없음. – mprabhat

+0

private 정수 ID = null; 학생 교실. 그 이드를 어떻게 생성 할 것입니까? 자동 생성? 그러면이 두 번째 모델과 첫 번째 모델의 차이점은 무엇입니까? –