简体   繁体   English

JPA和Hibernate Spring引导中的一对一共享主键单向映射

[英]JPA and Hibernate One To One Shared Primary Key Uni-directional Mapping in Spring Boot

I want to have one-to-one uni-directional mapping with 2 child entities using shared primary key.我想使用共享主键与 2 个子实体进行一对一的单向映射。 Below are model classes以下是 model 类

public class Template implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "templatekey")
    Integer templateKey;

    @Column(name = "templateid", unique = true)
    String templateId;
    
    @OneToOne(cascade = CascadeType.ALL, optional = false)
    @PrimaryKeyJoinColumn(name = "templatekey", referencedColumnName = "templatekey")
    InstantOfferNoEsp instantOfferNoEsp;

    @OneToOne(cascade = CascadeType.ALL, optional = false)
    @PrimaryKeyJoinColumn(name = "templatekey", referencedColumnName = "templatekey")
    Mobile mobile;

     //constructor , setter and getters

}

Child 1 :

public class Mobile implements Serializable {
   
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "templatekey")
    Integer templateKey;
    
    String mobileNewUrl;


    //constructor , setter and getters

}

Child 2:

public class InstantOfferNoEsp {

    @Id
    @Column(name = "templatekey")
    Integer templateKey;

    String offerCodeType;

    String headerUrl;
 
    //constructor , setter and getters
}

I want templateKey as PK in all tables.我希望 templateKey 在所有表中都作为 PK。 and I am calling templateRepository.save(template);我正在调用templateRepository.save(template); to save all entities at once but its not working and getting ids for this class must be manually assigned before calling save() error.一次保存所有实体,但它无法正常工作,并且ids for this class must be manually assigned before calling save()

Any suggestions would be of great help.任何建议都会有很大帮助。 Thank you.谢谢你。

I was able to do what you want with bidirectional @OneToOne like below:我可以使用双向@OneToOne做你想做的事情,如下所示:

@Entity
public class Mobile {

    @Id
    Integer templateKey;
    
    @OneToOne
    @MapsId
    @JoinColumn(name = "templatekey")
    Template template;

    // ...
}

@Entity
public class InstantOfferNoEsp {

    @Id
    Integer templateKey;

    @OneToOne
    @MapsId
    @JoinColumn(name = "templatekey")
    Template template;
 
    // ...
}


@Entity
public class Template {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "templatekey")
    Integer templateKey;

    
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "template", optional = false)
    InstantOfferNoEsp instantOfferNoEsp;

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "template", optional = false)
    Mobile mobile;

    // ...

    public void setMobile(Mobile mobile)
    {
        this.mobile = mobile;
        this.mobile.setTemplate(this);
    }

    public void setInstantOfferNoEsp(InstantOfferNoEsp instantOfferNoEsp)
    {
        this.instantOfferNoEsp = instantOfferNoEsp;
        this.instantOfferNoEsp.setTemplate(this);
    }
}

and an example of saving:和一个保存的例子:

Mobile mobile = new Mobile();
mobile.setMobileNewUrl("MOB1");

InstantOfferNoEsp instant = new InstantOfferNoEsp();
instant.setOfferCodeType("INST_OFF1");
      
Template template = new Template();
template.setTemplateId("TMP1");
template.setInstantOffer(instant);
template.setMobile(mobile);
entityManager.persist(template);

PS The following mapping works too, but only if we set Template.templateKey manually. PS 以下映射也有效,但前提是我们手动设置Template.templateKey

@Entity
public class Template
{
   @Id
   // @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name = "templatekey")
   Integer templateKey;

   @OneToOne(cascade = CascadeType.ALL, optional = false)
   @JoinColumn(name = "templatekey", insertable = false, updatable = false)
   InstantOfferNoEsp instantOfferNoEsp;

   @OneToOne(cascade = CascadeType.ALL, optional = false)
   @JoinColumn(name = "templatekey", insertable = false, updatable = false)
   Mobile mobile;
 
   // ...
}

and an example of saving:和一个保存的例子:

Mobile mobile = new Mobile();
mobile.setMobileNewUrl("MOB1");

InstantOfferNoEsp instant = new InstantOfferNoEsp();
instant.setOfferCodeType("INST_OFF1");
      
Template template = new Template();
template.setTemplateKey(20);
template.setTemplateId("TMP1");
template.setInstantOffer(instant);
template.setMobile(mobile);
entityManager.persist(template);

Also I would suggest your explicitly specify what generation strategy you want to use (do not use GenerationType.AUTO ) and use corresponding object wrapper classes instead of primitive types for @Id fields.另外,我建议您明确指定要使用的生成策略(不要使用GenerationType.AUTO )并使用相应的 object 包装类而不是@Id字段的原始类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM