【问题标题】:Hibernate OneToMany selects all child instances for every parent instancesHibernate OneToMany 为每个父实例选择所有子实例
【发布时间】:2014-09-10 07:54:33
【问题描述】:

我有两个与 OneToMany 关联的类 - ManyToOne 映射。 当我选择父实体时,它也会选择子实体,但是,分配给它的所有子实例都是每个父实例,而不是分配相关实例。

PurchaseEntry.java

@Entity
@Table(name="PURCHASE_ENTRY")
public class PurchaseEntry {

    public PurchaseEntry() {
    }
    @Id @Column(name="PURCHASE_ID") @GeneratedValue(strategy=GenerationType.AUTO)
    private long purchaseId;
    @Column(name="INVOICE_NO")
    private String invoiceNo;
    @Column(name="INVOICE_DATE")
    @Type(type="date")
    private Date invoiceDate;          

    @OneToMany(targetEntity=PurchaseDetails.class, cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinColumn(name="PURCHASE_ID")
    private Collection<PurchaseDetails> purchaseDetailsList = new ArrayList<PurchaseDetails>(); 
}

PurchaseDetails.java

@Entity
@Table(name = "PURCHASE_DETAILS")
public class PurchaseDetails {

    public PurchaseDetails() {
    }

    @Id
    @Column(name = "PURCHASE_DETAIL_ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long purchaseDetailId;
    @Column(name = "AMOUNT")
    private float amount;    

    @ManyToOne
    @JoinColumn(name = "PURCHASE_ID")
    private PurchaseEntry purchaseEntry;

}

当使用 PurchaseDetails.java 实例 Collection 保存 PurchaseEntry.java 对象时,它可以正常工作,但是在选择父表时,它会选择相关的子表行,但这相关的所有行都分配给每个父类对象

选择查询

Criteria criteria = session.createCriteria(PurchaseEntry.class)
                    .add(Restrictions.between("invoiceDate", fromFilterDate, toFilterDate)).addOrder(Order.asc("invoiceDate"));

            purchaseEntryList = criteria.list();

例如,Purchase_Entry 表有一行

purchase_id - 1, invoice_date - 2014 年 7 月 18 日

并且 Purchase_details 表有

PURCHASE_DETAIL_ID - 1, purchase_id - 1, ...

PURCHASE_DETAIL_ID - 2, purchase_id - 1, ...

PURCHASE_DETAIL_ID - 3, purchase_id - 1, ...

当我使用 invoice_date '18-07-2014' 的条件选择 PurchaseEntry 时,它返回 3 个 PurchaseEntry 对象,在每个 PurchaseEntry 对象中 purchaseDetailsList 有 3 个与 purchase_id = 1

我的配置或其他配置有什么问题???

预期 : 每个 PurchaseEntry 对象在 purchaseDetailsList 中只有一个相关的 PurchaseDetails 实例

【问题讨论】:

    标签: hibernate jpa hibernate-mapping hibernate-onetomany


    【解决方案1】:

    不幸的是,我使用下面的代码找到了答案

    @OneToMany(cascade=CascadeType.ALL) 
        @JoinColumn(name="PURCHASE_ID")
        @Fetch(FetchMode.SELECT)
        private Collection<PurchaseDetails> purchaseDetailsList = new ArrayList<PurchaseDetails>();
    

    添加 @Fetch(FetchMode.SELECT) 按我的预期工作,我也重新创建了我的架构

    【讨论】:

      【解决方案2】:

      我认为您不需要在PurchaseEntry 中提供@JoinColumn。也不需要给出targetEntity,因为它可以推断类型。

      试试这个配置。

      @OneToMany(mappedBy="purchaseEntry", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
          private Collection<PurchaseDetails> purchaseDetailsList = new ArrayList<PurchaseDetails>(); 
      

      【讨论】:

      • 阿米特 - 不,它不起作用,当我删除 @JoinColumn 注释时,值不会在保存时插入到该连接列中。但不需要在 PurchaseEntry 中指定 targetEntity,因为你说工作正常,但我的预期结果没有出现。
      【解决方案3】:

      Hibernate 关系映射会将每个对象与相关对象关联起来,就像如果一个表与另一个表相关,那么它将从两个表中获取。您可以使用不同的获取策略来智能地获取数据。

      在你的情况下,

      fetch=FetchType.EAGER

      会在开始时自己获取所有记录,但FetchType.lazy 的使用只会在其需要时获取。

      您可以查看不同的fetch strategies here 了解更多详情。

      【讨论】:

      • 但我必须从我的视图(JSP)中调用 'purchaseEntryList.get(0).purchaseDetailsList' 这就是为什么我使用 'fetch=FetchType.EAGER' 如果我使用 'FetchType.lazy' 时尝试获取 purchaseDetailsList 它抛出异常
      • 是的,它会抛出异常,因为访问数据库的权限不会出现在 jsp 中。您必须了解它发生的原因,如果您想在单个查询中获取数据,那么您必须使用连接查询。否则,您至少可以使用SUBSELECT,我提供的链接中对此进行了说明。
      猜你喜欢
      • 2017-08-02
      • 1970-01-01
      • 1970-01-01
      • 2011-09-11
      • 1970-01-01
      • 2013-06-10
      • 2016-06-11
      • 2016-01-02
      • 1970-01-01
      相关资源
      最近更新 更多