gpt4 book ai didi

java - 使用 Hibernate 获取重复条目

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:32:31 34 4
gpt4 key购买 nike

我在使用 JPA/Hibernate 时遇到了一个奇怪的问题。我在测试期间看到重复的条目。

这是我的 BaseEntity 类:

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class BaseEntity {

@Id
@Column(name = "ID", updatable = false, nullable = false)
@GenericGenerator(name = "uniqueIDGenerator", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator", parameters = {
@org.hibernate.annotations.Parameter(name = "sequence_name", value = "ID_SEQUENCE"),
@org.hibernate.annotations.Parameter(name = "increment_size", value = "100"),
@org.hibernate.annotations.Parameter(name = "optimizer ", value = "pooled") })
@GeneratedValue(generator = "uniqueIDGenerator")
@NotNull
protected int id;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

}

这是我的主要合作伙伴类:

@Entity
@Table(name = "partner")
public class Partner extends BaseEntity{

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

@OneToMany(mappedBy="partner", fetch=FetchType.EAGER)
@Cascade(CascadeType.DELETE)
private List<Receipt> receipts;

@OneToMany(mappedBy="partner", fetch=FetchType.EAGER)
@Cascade(CascadeType.DELETE)
private List<Delivery> deliveries;

public Partner() {
setReceipts(new ArrayList<Receipt>());
setDeliveries(new ArrayList<Delivery>());
}

public Partner(String name){
this();

this.setName(name);
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public List<Receipt> getReceipts() {
return receipts;
}

public void setReceipts(List<Receipt> receipts) {
this.receipts = receipts;
}

public List<Delivery> getDeliveries() {
return deliveries;
}

public void setDeliveries(List<Delivery> deliveries) {
this.deliveries = deliveries;
}
}

Partner 有两个子类,Receipt 和 Delivery。这是收据类:

@Entity
@Table(name = "receipt")
public class Receipt extends BaseEntity{

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="partnerId")
private Partner partner;

@Column(name = "name")
private String name;
@Column(name = "json")
private String json;

@Transient
private ReceiptContainer receiptContainer;


public Receipt() {
}
public Receipt(String name){
this();

this.setName(name);
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getJson() {
return json;
}

public void setJson(String json) {
this.json = json;
}

public ReceiptContainer getReceiptContainer() {
return receiptContainer;
}

public void setReceiptContainer(ReceiptContainer receiptContainer) {
this.receiptContainer = receiptContainer;
}

public Partner getPartner() {
return partner;
}

public void setPartner(Partner partner) {
this.partner = partner;
}

}

这是交付类:

@Entity
@Table(name = "delivery")
public class Delivery extends BaseEntity{

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="partnerId")
private Partner partner;

@Column(name = "name")
private String name;
@Column(name = "json")
private String json;

@Transient
private DeliveryContainer deliveryContainer;


public Delivery() {
}
public Delivery(String name){
this();

this.setName(name);
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getJson() {
return json;
}

public void setJson(String json) {
this.json = json;
}

public DeliveryContainer getDeliveryContainer() {
return deliveryContainer;
}

public void setDeliveryContainer(DeliveryContainer deliveryContainer) {
this.deliveryContainer = deliveryContainer;
}

public Partner getPartner() {
return partner;
}

public void setPartner(Partner partner) {
this.partner = partner;
}

}

我得到的对象是这样的:

@Transactional
public Partner get(int id){
Partner partner = entityManager.find(Partner.class, id);
return partner;
}

可以看到,partner类包含了一个List of objects和一个List of objects,分别存储在各自的表中,receipt和delivery。

---在我继续之前,我想注意数据库中显示的条目数是正确的。只有在我的 Java 应用程序中获取对象时才会出现此问题。---

当我添加一个对象并且没有对象存在时,显示一个对象并且没有显示任何对象,这是预期的。如果存在一个对象和一个对象,则再次显示一个对象和一个对象,这是预期的。当存在多个或对象时会出现此问题。例如,如果添加了两个对象,但只添加了一个对象,则显示两个对象AND 两个对象。

为了更好地说明这一点,请参阅下面的测试用例表。意外结果用破折号包围。

<Receipt> Obj Added | <Delivery> Obj Added | <Receipt> Obj Displayed | <Delivery> Obj Displayed
0 | 0 | 0 | 0
0 | 1 | 0 | 1
1 | 0 | 1 | 0
1 | 1 | 1 | 1
1 | 2 | ---2--- | ---2---
2 | 1 | ---2--- | ---2---
2 | 2 | ---4--- | ---4---

我的问题是,为什么我会看到这些意想不到的结果?

最佳答案

您看到重复的原因是因为您急切地获取子项,这正在创建一个外部连接。

(您可以使用@Fetch(FetchMode.SELECT),但这会导致额外的查询来检索您的项目)

Hibernate API reference indicating outer join takes place.

以下是对您问题的深入解答:Hibernate Criteria returns children multiple times with FetchType.EAGER

您可以从 List 切换到 Set(如果这样做,请确保覆盖 equals/compareTo/hashCode)。或者,如果您通过条件从数据库中提取这些项目,则可以将结果转换器添加到查询结果中。

就其值(value)而言,hibernate 建议使用集合而不是列表

关于java - 使用 Hibernate 获取重复条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26763213/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com