我的用例需要帮助。我有一个 Order
实体
@Entity
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@ManyToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
@JoinTable(name = "inconsistent_orders",
joinColumns = @JoinColumn(name = "order_id"),
inverseJoinColumns = @JoinColumn(name = "inconsistency_id")
)
private Set<OrderInconsistency> inconsistencies;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Set<OrderInconsistency> getInconsistencies() {
return inconsistencies;
}
//getters and setters ommitted for brevity
public void setInconsistencies(Set<OrderInconsistency> inconsistencies) {
this.inconsistencies = inconsistencies;
this.inconsistencies.forEach(i -> i.setOrders(List.of(this)));
}
//hashcode and equals ommitted for brevity
}
和一个 OrderInconsistency
实体
@Entity
@Table(name = "order_inconsistencies")
public class OrderInconsistency {
@Id
@Column(name = "id")
private String id;
@Basic
@Column(name = "description")
private String description;
@ManyToMany(mappedBy = "inconsistencies")
private List<Order> orders = new ArrayList<>();
public OrderInconsistency() {
}
public OrderInconsistency(String id, String description) {
Assert.notNull(id, "El id de la inconsistencia no puede ser null");
this.id = id.replaceAll(" ", "_").toUpperCase();
this.description = description;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Order> getOrders() {
return orders;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
OrderInconsistency that = (OrderInconsistency) o;
return id.equals(that.id);
}
@Override
public int hashCode() {
return id.hashCode();
}
}
我的多对多表:
CREATE TABLE `inconsistent_orders`
(
`order_id` INT(11) NOT NULL,
`inconsistency_id` VARCHAR(25) NOT NULL,
PRIMARY KEY (`order_id`, `inconsistency_id`),
FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (`inconsistency_id`) REFERENCES `order_inconsistencies` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE = InnoDB;
我们的想法是 Order
是这段关系的父对象,所以当我保存 Order
,它应该保存其不一致性(如果有)。
订单不一致性在创建后不会改变。例如,如果一个新的 Order
得到保存,它有一个 OrderInconsistency
带着身份证 TOTALS_DONT_MATCH
,并且与该id的不一致性还不存在,jpa应该在保存订单之前创建它,然后将它添加到 Set
顺序上的不一致。
将来,其他订单可能会有这种不一致性,因为它已经存在于db中,jpa不应该创建它,而只是将它添加到多对多表中 inconsistent_orders
.
但是,我面临的问题是,即使我手动将一个已经存在的id分配给手动创建的示例 OrderInconsistency
,jpa试图插入它,从而导致重复输入错误。
总而言之,我第一次保存订单时,它工作正常 OrderInconsistency
得到保存。如果另一个 Order
得到保存,它也有相同的 OrderInconsistency
,jpa尝试插入它,即使它已经存在并且失败了。
例如
@Transactional
public ValidatedOrderDTO saveConsistentOrder(Order order) {
boolean consistentOrder = true;
var orderInconsistencies = new HashSet<OrderInconsistency>();
for (OrderValidationService validationService : orderValidationServices) {
ValidationResult validationResult = validationService.validate(order);
if (!validationResult.isValid()) {
// this returns a manually created instance of OrderConsistency with an ID that already exists in the DB
OrderInconsistency inconsistency = validationResult.getOrderInconsistency();
orderInconsistencies.add(inconsistency);
consistentOrder = false;
}
}
order.setInconsistencies(orderInconsistencies);
ordersDAO.save(order); //here, JPA attempts to INSERT the OrderInconsistency even though it already exists in DB
return new ValidatedOrderDTO(consistentOrder, consistenciesDescription);
}
我想出的解决办法是 OrderInconsistencyDAO
和手动 findById
如果不一致,则将其添加到 Order
,如果不是,则将新示例分配给 Order
. 我不明白为什么这样做,如果这是正确的方法。它是否与托管和非托管实体有关?
工作的例子-我不明白为什么它有效
@Transactional
public ValidatedOrderDTO saveConsistentOrder(Order order) {
boolean consistentOrder = true;
var orderInconsistencies = new HashSet<OrderInconsistency>();
for (OrderValidationService validationService : orderValidationServices) {
ValidationResult validationResult = validationService.validate(order);
if (!validationResult.isValid()) {
OrderInconsistency inconsistency = validationResult.getOrderInconsistency();
Optional<OrderInconsistency> orderInconsistencyOpt = orderInconsistenciesDAO.findById(inconsistency.getId());
if (orderInconsistencyOpt.isEmpty()) {
orderInconsistenciesDAO.save(inconsistency);
} else {
inconsistency = orderInconsistencyOpt.get();
}
orderInconsistencies.add(inconsistency);
consistentOrder = false;
}
}
order.setInconsistencies(orderInconsistencies);
ordersDAO.save(order);
return new ValidatedOrderDTO(consistentOrder, consistenciesDescription);
}
暂无答案!
目前还没有任何答案,快来回答吧!