我想创建一个表,其中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",
joinColumns=@JoinColumn(name="mediaLocator_id"),
inverseJoinColumns=@JoinColumn(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)
。
通过这种方式,由于与其他对象的关系引用,我无法存储数据
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",
joinColumns=@JoinColumn(name="mediaLocator_id"),
inverseJoinColumns=@JoinColumn(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 :(得分:2)
将属性移动到可嵌入类后,需要将它们从主类中删除,只有一个嵌入类的引用,因此在您的示例中,您需要从{{1}中删除所有属性,如位置}。class。
财产MediaLocator
在你的id
中做了什么?由于您的类中没有特定的列注释,因此hibernate会尝试将每个属性映射到表列,如果属性和表列的命名相同,它将在该映射中成功。
如果您不需要MediaLocator
,请将其删除或将其标记为id
。
这段代码将重现您所获得的相同错误。
学生班
@Transient
学生PK课程:
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;
}
}
地址类
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)
中的多少人被打破了。
现在这件作品应该可行:
学生班
StudentMTM
学生PK
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;
}
}
地址类 - 与第一个版本相比没有变化。
在第二个版本中,JoinColumn是Student的一部分,映射知道它映射到的位置。