通过 JPA 注释的聚合关系

Aggregation relationship via JPA annotations

我正在尝试通过 JPA 注释在两个 Java class 之间建立聚合关系,以便将它们持久化到数据库中。

public class Ticket 
{
    private String ticketNo;
    private Date releasedDate;
    private boolean printed;
}

public class Discount 
{
    private String percentage;
    private Date releasedDate;
    private boolean printed;
}

如提到的here, the aggregation relationship is unidirectional and thus, only it is necessary to map one side. From the solution given by this page,我认为解决方案是:

 public class Discount 
    {
        private String percentage;
        private Date releasedDate;
        private boolean printed;
        @ManyToOne(name="TICKET_ID")
        private Ticket ticket;
    }

然而,在一些examples of aggregation中,多边class出现在单边class里面。所以,我也在考虑这个:

 public class Ticket 
        {
            private String ticketNo;
            private Date releasedDate;
            private boolean printed;
            @OneToMany(mappedBy="ticket")
            private List<Discount> discounts = new ArrayList<Discount>();
        }

哪个选项是正确的?

我觉得很合适。一折就有票。如果您需要在 SELECT t FROM Ticket t WHERE t.discounts.percentage >= :discountPercentage.

等查询中访问它们,您还可以包括可从 ticket.getDiscounts() 等门票获得的折扣
@Entity
public class Ticket {
    @Id
    private String ticketNo;
    private Date releasedDate;
    private boolean printed;

    @OneToMany(mappedBy = "ticket", fetch = FetchType.LAZY)
    private List<Discounts> discounts;
}

@Entity
public class Discount {
       private String percentage;
       private Date releasedDate;
       private boolean printed;

       @ManytoOne(name="TICKET_ID")
       private Ticket ticket;
}

但是,我不建议使用 @OneToMany,因为如果您将其作为 JSON 结果返回或只是延迟加载,那么将太多数据序列化到 JSON 会产生问题很多数据是偶然的。如果您没有将 @OneToMany 关联查询设置为 SELECT t FROM Discount d INNER JOIN d.ticket t WHERE d.percentage >= :discountPercentage

,您应该始终能够仅以 @ManyToOne 为例

这是映射单向多对一关系的方式:

@Entity
public class Ticket {
    @Id
    @GeneratedValue
    private Long id;

    private String ticketNo;
    private Date releasedDate;
    private boolean printed;

    // getters and setters
}

@Entity
public class Discount {
    @Id
    @GeneratedValue
    private Long id;

    private String percentage;
    private Date releasedDate;
    private boolean printed;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "TICKET_ID")  // you can rename the join column 
    private Ticket ticket;

    // getters and setters
}

注:

  • JoinColumn(数据库术语中的外键)必须在关系的多边(这是您的情况下的折扣)。
  • @Id 注释也是强制性的。在这种情况下,ID 将由持久性提供程序自动生成。如果您正在使用数据库序列或 table 或其他一些策略,您可以重新定义它。