簡體   English   中英

帶有共享主鍵的Hibernate JPA一對一映射導致問題

[英]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

有人可以告訴我如何解決此問題嗎?

您必須手動設置對象MediaDetailsid或向其添加@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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM