java – 没有关系的JPA外键

我有两个实体邮件和附件.我想在它们之间创建一个约束但不映射关系.

例如:

class Mail {

    @Id
    private String id;

    ...
} 

class Attachment {

    @Id
    // @... constraint with Mail.id ???
    private String mailId;

    @Id
    private String id;

    ...
}

所以这只是一个临时的例子来解释.在这种情况下,如何让JPA创建约束而不必强制在附件中映射Mail?

我不想这样做:

class Attachment {

    @Id
    @ManyToOne
    private Mail mail;

    @Id
    private String id;

    ...
}

最佳答案 JPA通过关系注释(如@OneToMany或@ManyToOne)创建两个实体之间的约束和关系.如果没有这些注释,您必须自己手动强制执行约束和关系.

例如,您可以在Mail上使用工厂方法创建Attachement在此工厂方法中实现其约束,并确保只能通过此方法创建Attachement.

public class Mail{

   @Id
   private String id;

   public Attachement createAttachement(){
      return new Attachement(id);
   }
}

public class Attachement{

    @Id
    private String id;

    @Column(name="mail_id")
    private String mailId;

    /***************************************************************************
      I will put all the domain class in the same package and make the 
      constructor as package scope to reduce the chance that this  
      object is created by other class accidentally except Mail class.
    **************************************************/
    Attachement(String mailId){
       this.mailId = mailId;
   }
}

然后实现一个服务类来协调有关Mail的业务用例的所有事情.客户端应该使用此服务类来管理邮件.例如:

public class MailService{

     private EntityManager em;

     @Transcational
     public void createMailWithAttachement(){
        Mail mail = new Mail(xxxx);
        em.persist(mail);

        Attachement attachement = mail.createAttachement();
        em.persist(attachement);
     } 


     @Transcational
     public void newAttachmentOnMail(String mailId, XXXXX){
       Mail mail = em.find(mailId, Mail.class);

       if (mail == null){
         throws new ApplicationException("Mail does not exist.Please Check");
        }

        Attachement attachement = mail.createAttachement();
        em.persist(attachement); 
    }              
 }
点赞