gpt4 book ai didi

spring - 单个事务中的多个 Spring Data JPA 存储库

转载 作者:行者123 更新时间:2023-12-02 21:19:50 25 4
gpt4 key购买 nike

我正在尝试映射以下代码: * 订单包含多个OrderItems * 文章可以被(包含)许多OrderItems引用

在一项事务中,我需要创建订单、多篇文章以及包含新文章的 OrderItems。当有直线路径时,一切都清楚了 - 订单包含 OrderItems 等等 - 然后我可以调用

orderRepository.save(order);
orderRepository.flush();

保存带有 OrderItems 实体的新订单实体。问题始于尝试保存 Article 实体。显然需要更多的工作,因为我收到错误消息;

org.springframework.dao.InvalidDataAccessApiUsageException: 
org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing

如何在一次事务中组织此类工作?多个存储库是否可以在单个事务下工作,如果可以,则由其flush() 完成事务。是否有必要进行多次刷新(例如,一个用于文章实体,另一个用于订单),如果是的话 - 如何在必要时回滚所有刷新?

显然不可能将存储库与简单的 EntityManager.getTransaction().{begin(), commit()} 代码混合使用,因为错误消息是:

java.lang.IllegalStateException: Cannot obtain local EntityTransaction from a transaction-synchronized EntityManager

如果一个实体 (OrderItem) 由两个实体(订单和文章)拥有,并且所有三个实体都应在一个事务中创建,那么最佳实践是什么?

添加了部分代码。 CompleteOrder 是测试过程,其中为新订单创建 5 个项目和 5 个新文章。此过程给出了异常“引用和未保存的 transient 实例”。我正在为 Article 实体使用复合键,但这不应该成为问题,我现在正在尝试使用具有通常单字段键的 Article 实体进行相同的场景。

@Entity
public class Order extends FrameworkEntity {
...
@OneToMany(mappedBy="order", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<OrderItem> orderItems = new ArrayList<OrderItem>();
}


@Entity
public class OrderItem extends FrameworkEntity {
...
@ManyToOne
@JoinColumn(name="fk_order")
private Order order;

@ManyToOne
@JoinColumns({
@JoinColumn(name="fk_date"),
@JoinColumn(name="fk_number")
})
private Article article;
}

@Entity
public class Article extends FrameworkEntity {
...
@Id
protected PkArticle pkArticle;

@OneToMany(mappedBy="article", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<OrderItem> orderItems = new ArrayList<OrderItem>();
}

@Embeddable
public class PkArticle extends FrameworkCompositeKey {

@Column(name = "article_number")
private Long articleNumber;

@Temporal(TemporalType.DATE)
@Column(name = "article_date")
private Date articleDate;
...
}


public class OrderService {

public void completeOrder() {

Order entity = new Order();
for (int i=0; i<5; i++) {
Date articleDate;
Long articleNumber;

Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(0);
cal.set(2015, 1, 31, 0, 0, 0);
articleDate = cal.getTime();
articleNumber = (new Random()).nextLong();

Article article = new Article(articleNumber, articleDate);

//entityManager.getTransaction().begin();
//entityManager.persist(space);
//entityManager.getTransaction().commit();

OrderItem item = new OrderItem();

item.setArticle(article);
article.getOrderItems().add(item);

item.setOrder(entity);
entity.getOrderItems().add(item);
}
entity=(Order) repository.save(entity);
repository.flush();
}
]

最佳答案

你有这样的代码吗?

@Entity
public class OrderItem {
@ManyToOne
private Article article;
}

如果是,请将其更改为:

@Entity
public class OrderItem {
@ManyToOne(cascade = CascadeType.PERSIST)
private Article article;
}

这将确保当新的 OrderItem 具有尚未保存的 Article 被持久化时,Article 将被保存也是如此。

关于spring - 单个事务中的多个 Spring Data JPA 存储库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28375498/

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