有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

双向一对多映射时插入后生成的java更新

出于性能原因,我使用双向一对多关系映射,以便在持久化实体时只生成inserts(根据What is the difference between Unidirectional and Bidirectional JPA and Hibernate associations? 中的一个答案)

然而,当我没有在多方面指定CascadeType.PERSIST时,我注意到在插入之后仍然会生成更新

Hibernate: insert into promotion (deadline, description, percentage, promotion_id) values (?, ?, ?, ?)
Hibernate: update product set amount_in_stock=?, category_id=?, description=?, product_name=?, product_price=?, production_year=?, promotion_id=?, "size"=?, sold_amount=?, vendor=?, weight=? where product_id=?

Promotion可以指许多Product

@Entity
@Table(name = "product")
public class Product
{
    @Id
    @Column(name = "product_id")
    @SequenceGenerator(name = "product_id_sequence", sequenceName = "product_id_sequence", allocationSize = 1)
    @GeneratedValue(generator = "product_id_sequence", strategy = GenerationType.SEQUENCE)
    private Long productId;

    @ManyToOne(fetch = FetchType.LAZY) // cascade = CascadeType.PERSIST
    @JoinColumn(name = "promotion_id")
    private Promotion promotion;
   
    // setters, getters, other fields
}
@Entity
@Table(name = "Promotion")
public class Promotion
{
    @Id
    @Column(name = "PROMOTION_ID")
    @SequenceGenerator(name = "promotion_id_sequence", sequenceName = "promotion_id_sequence", allocationSize = 1)
    @GeneratedValue(generator = "promotion_id_sequence", strategy = GenerationType.SEQUENCE)
    private Long promotionId;

    @OneToMany(mappedBy = "promotion", cascade = CascadeType.ALL)
    private List<Product> products = new LinkedList<>();

    public void addProduct(Product product)
    {
        products.add(product);
        product.setPromotion(this);
    }
    // setters, getters, delete synchronization method, other fields
}

持久化逻辑(@DataJpaTest):

promotion.addProduct(product);
entityManager.persist(promotion);
entityManager.flush();

为什么会这样

谢谢你的阅读


共 (1) 个答案

  1. # 1 楼答案

    它发生了,因为在测试中,我保存了多个与Product相关的实体。然后,当Product处于管理状态时,通过调用entityManager.persist(promotion);,hibernate必须通过添加promotion_id键来更新Product

    entityManager.persist(category); // category has many products (CascadeType.ALL added)
    entityManager.persist(promotion);
    entityManager.flush();
    

    我应该提供更多的测试方法,但坦率地说,我不知道它们有一些影响。总之,这不是一个映射问题,而是一个保持实体之间关系的顺序。最后

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "promotion_id")
    private Promotion promotion;
    

    是正确的,在Product端不需要额外的级联