![](/img/trans.png)
[英]JPA / Hibernate unidirectional one-to-one mapping with shared primary key
[英]Hibernate JPA one to one mapping with share primary key is causing the Issue
嗨,我是Hibernate JPA的新手。 我正在使用eclipse kepler 4.3.2並創建一個簡單的Java項目。 我在具有共享主鍵的實體MediaRequestDetails和MediaDetails.java對象之間有一個簡單的一對一映射。
類MediaRequestDetails(COLUMN="ID")
的主鍵是通過序列生成的,並且此字段requestId的值已與類MediaDetails.java(COLUMN="REQUEST_ID")
共享。我具有這樣的源實體MediaRequestDetails跳過了getter和setter以及從源代碼中導入包的過程。
@Entity
@Table(name = "AW_REQUEST_DETAILS1")
public class MediaRequestDetails implements WFPayload , Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@SequenceGenerator(name="REQUEST_ID_SEQ", sequenceName="REQUEST_ID_DBSEQ", allocationSize=1, initialValue = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "REQUEST_ID_SEQ")
@Column(name = "ID", nullable = false)
Long requestId;//id of the request
@Column(name="REQUEST_TYPE", nullable = false)
String requestType;//Type of the request Media/Non Media
@Column(name="REQUESTOR", nullable = false)
String requestor;//SOE ID of the requestor
@Column(name="REQUESTOR_REGION")
String requestorRegion;//This will be auto populated once the requestor is been added.
@Column(name="REQUESTOR_TYPE")
String requestorType;//requestortype OBO,analyst or Coprorate Affairs
@Column(name="EVENT_DATETIME")
@Temporal(TemporalType.TIMESTAMP)
Date eventDate;//Date of the event // Please capture sate timezone as well
@Column(name="EVENT_TYPE_ID")
long eventType;//Type of the event
@Column(name="PRINTED_MTRL")
@Type(type="yes_no")
boolean printedMTRL;//printed material will be produced or not
@Column(name="IS_LOCATION_USA")
@Type(type="yes_no")
boolean locationIsUsa;//flag will this take place in USA or Not
@Column(name="IS_ANALYST_ATTESTATION")
@Type(type="yes_no")
boolean hasAnalystAtts;
@Column(name="ANALYST_ATTESTATION")
String analystAtts;//AnalystAttastation
@Column(name="ANALYST_DISCLOSURE")
String analystDisclosure;//AnalystDisclosure
@Column(name="ANALYST_DERV_POS")
@Type(type="yes_no")
boolean analystDervPos;//Information Regarding the Derivative Position(Y/N)
@Column(name="ANALYST_POS_DETAILS")
String analystPosdetails;//Information regarding Disclosure
@Column(name="LAST_MODIFIED_BY")
String lastModifiedBy;//media request modified by name
@Column(name="LAST_MODIFIED_DATE")
@Temporal(TemporalType.TIMESTAMP)
Date lastModifiedDate;//date of the media request modified
@Column(name="REQ_CREATED_BY")
String createdBy;//media requestor creator user SOE Id.
@Column(name="REQ_CREATE_DATE")
@Temporal(TemporalType.TIMESTAMP)
Date createDate;//media requestor creator user SOE Id.
@Column(name="REQUEST_STATUS")
String requestStatus;//Setting the status of the Request
@Column(name="PROCESS_INSTANCE_ID")
Long procInstId;
@Column(name="RSCH_APPRVL_FILE")
@Lob
byte[] rschApprvlFile;//Attached the approval of Research Management group
@Column(name="CORP_APPRVL_FILE")
@Lob
byte[] coprApprvlFile;//Attached approval of coprorate group.
@Column(name="IS_APPRVL_BY_CORP")
@Type(type="yes_no")
boolean hasApprovedByCorporate;//is request been approved by corporate
@Column(name="IS_APPRVL_BY_RSCH")
@Type(type="yes_no")
boolean hasApprovedByRschMgmt;//is request been approved by rsch management
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name="REQUEST_ID", referencedColumnName="ID")
Set<RequestDetailsCompanies> reqCompNotFoundDetails;
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name="REQUEST_ID", referencedColumnName="ID")
Set<RequestDetailsCompanies> reqCompDiscussDetails;//Companies that are to be discussed
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name="REQUEST_ID", referencedColumnName="ID")
Set<RequestDetailsCompanies> reqCompMayDiscussDetails;//Companies that may be discussed
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name="REQUEST_ID",referencedColumnName="ID")
Set<RequestDetailsCountries> reqContDiscussDetails;//Countries that are to be discussed
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name="REQUEST_ID",referencedColumnName="ID")
Set<RequestDetailsCountries> reqContMayDiscussDetails;///Countries that are to be discussed
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn(columnDefinition="ID",referencedColumnName="REQUEST_ID")
MediaDetails mediaDetails;//store the details of media in case of MeediaAppearance
//getter setter methods for the fields
}
MediaDetails.java的源代碼。 我從類源代碼中跳過了包的導入以及getter和setter方法。
@Entity
@Table(name = "AW_MEDIA_DETAILS")
public class MediaDetails implements WFPayload , Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@Column(name = "REQUEST_ID", unique = true, nullable = false)
Long requestId;
@Column(name="MEDIA_NAME")
String mediaName;
@Column(name="INTERVIEWER")
String interviewer;
@Column(name="EMAIL")
String email;
@Column(name="PHONE_NO")
String phoneNo;
@Column(name="INTRW_DETAILS")
String intrwDetails;
@OneToOne(mappedBy="mediaDetails", cascade=CascadeType.ALL)
private MediaRequestDetails mediaRequDetails;
//getter and setter methods are here
}
我正在使用下面的源代碼來保存數據,但是在將數據保存到與MediaDetails.java類關聯的表中時會導致問題
public class TestRawsConnection {
public static void main(String args[]){
EntityManager entityManager = Persistence.createEntityManagerFactory("rawsjpa").createEntityManager();
if(entityManager!=null){
System.out.println("************* EntityManager is obtained 1234*****************");
Date dt=new Date();
entityManager.getTransaction().begin();
MediaRequestDetails obj=new MediaRequestDetails();
obj.setRequestor("jinesh");
obj.setRequestorRegion("USA");
obj.setRequestorType("OBO");
obj.setRequestType("MediaAppr");
obj.setEventDate(dt);
obj.setEventType(12);
obj.setLocationIsUsa(true);
obj.setPrintedMTRL(false);
obj.setLocationIsUsa(false);
obj.setHasAnalystAtts(true);
obj.setAnalystAtts("analystattestation");
obj.setAnalystDisclosure("analystdisclosure");
obj.setAnalystDervPos(true);
obj.setAnalystPosdetails("analystposdetails");
obj.setLastModifiedBy("jinesh");
obj.setLastModifiedDate(dt);
obj.setCreatedBy("jinesh123");
obj.setCreateDate(dt);
obj.setRequestStatus("pending");
obj.setProcInstId(1234L);
obj.setHasApprovedByCorporate(true);
obj.setHasApprovedByRschMgmt(true);
obj.setCoprApprvlFile(new String("Jinesh parikh").getBytes());
obj.setRschApprvlFile(new String("Sejal Mehta").getBytes());
MediaDetails md=new MediaDetails();
md.setMediaName("test");
obj.setMediaDetails(md);
md.setMediaRequDetails(obj);
entityManager.persist(obj);
entityManager.getTransaction().commit();
}
}
以下是在將對象保存到數據庫時遇到的異常。
************* EntityManager is obtained 1234*****************
Hibernate: select REQUEST_ID_DBSEQ.nextval from dual
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): com.cira.raws.mediawf.bean.impl.MediaDetails
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1316)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:881)
at TestRawsConnection.main(TestRawsConnection.java:60)
Caused by: org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): com.cira.raws.mediawf.bean.impl.MediaDetails
at org.hibernate.id.Assigned.generate(Assigned.java:52)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:117)
at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:78)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:762)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:755)
at org.hibernate.ejb.engine.spi.EJB3CascadingAction$1.cascade(EJB3CascadingAction.java:53)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:396)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:339)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:207)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:164)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:449)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:292)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:192)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:135)
at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:78)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:78)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:772)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:746)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:750)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:875)
... 1 more
有人可以告訴我如何解決此問題嗎?
您必須手動設置對象MediaDetails
的id
或向其添加@GeneratedValue
批注。 是否應由數據庫設置。
這是自動遞增的示例:
@Entity
@Table(name = "AW_MEDIA_DETAILS")
public class MediaDetails implements WFPayload , Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "REQUEST_ID", unique = true, nullable = false)
Long requestId;
....
似乎您正在創建一對一關系,您想在兩個實體類(MediaRequestDetails和MediaDetails)中使用相同的主鍵標識符。 在這種情況下,MediaDetails的主鍵也將是MediaRequestDetails的外鍵 。
您需要做的是將@PrimaryKeyJoinColumn批注放入MediaDetails類中,尤其是放在MediaDetails實體類的MediaRequestDetails字段上。 換句話說,您必須撤消關系的所有權。 我還添加了@GenericGenerator批注,為MediaDetails標識符指定了外來策略。
在MediaRequestDetails中,刪除了主要聯接列約束,並且@OneToOne批注必須指定mappingBy元素。
@Entity
@Table(name = "AW_REQUEST_DETAILS1")
public class MediaRequestDetails ... {
@Id
@SequenceGenerator(name="REQUEST_ID_SEQ", sequenceName="REQUEST_ID_DBSEQ", allocationSize=1, initialValue = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "REQUEST_ID_SEQ")
@Column(name = "ID", nullable = false)
Long requestId;//id of the request
. . .
@OneToOne(mappedBy="mediaRequDetails", cascade = CascadeType.ALL)
MediaDetails mediaDetails;//store the details of media in case of MeediaAppearance
// getter and setter methods
}
@Entity
@Table(name = "AW_MEDIA_DETAILS")
@org.hibernate.annotations.GenericGenerator(name="mediaRequDetails-primarykey", strategy="foreign",
parameters={@org.hibernate.annotations.Parameter(name="property", value="mediaRequDetails")
})
public class MediaDetails ... {
@Id
@GeneratedValue(generator="mediaRequDetails-primarykey")
@Column(name = "REQUEST_ID", unique = true, nullable = false)
Long requestId;
. . .
@OneToOne
@PrimaryKeyJoinColumn
private MediaRequestDetails mediaRequDetails;
// getter and setter methods
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.