CascadeType.ALL和“ insertable = false,可更新= false”是否互相排斥?

问题描述 投票:0回答:1

如果我有这样的配置,可以使用吗?

@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "FOREIGN_ID", nullable = false, insertable = false, updatable = false)
ForeignClass foreignClass;

我不认为,因为级联类型的行为与可插入和可更新的参数冲突。

你怎么看?

java hibernate spring-data-jpa spring-data hibernate-mapping
1个回答
0
投票

长话短说,不,这些设置不会互相排斥。

想象一下,我们有以下模型。

create table APP_USER
(
   USER_ID number,
   USER_NAME varchar2(400),

   constraint APP_USER_PK primary key(USER_ID)
);

create table APP_BILLING_NUMBER
(
   BILL_ID number,
   BILL_ACCOUNT varchar2(20),
   BILL_BANK_NAME varchar2(300),
   BILL_USER_ID number,

   constraint APP_BILLING_NUMBER_PK primary key(BILL_ID),
);

以及适当的休眠映射:

@Entity
@Table(name = "APP_USER")
public class User
{
   @Id
   @Column(name = "USER_ID")
   private Long id;

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

@Entity
@Table(name = "APP_BILLING_NUMBER")
public class BillingNumber
{
   @Id
   @Column(name = "BILL_ID")
   private Long id;

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

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

   @ManyToOne
   @JoinColumn(name="BILL_USER_ID")
   private User user;
}

如果我们尝试做这样的事情:

  User user = new User();
  user.setId(1L);
  user.setName("Alex");

  BillingNumber bill = new BillingNumber();
  bill.setId(1L);
  bill.setAccount("EA12345678");
  bill.setBankName("BNP Paribas");
  bill.setUser(user);

  session.persist(bill);

我们将发现帐单已添加到APP_BILLING_NUMBER表,

SQL> select * from APP_BILLING_NUMBER;
BILL_ID BILL_ACCOUNT BILL_BANK_NAME BILL_USER_ID
------- ------------ -------------- ------------
1       EA12345678   BNP Paribas    1

但用户不是。发生这种情况是因为默认情况下,我们有@ManyToOne(cascade={})。如果我们想将User实体与BillingNumber实体保持在一起,则应添加CascadeType.PERSIST

  @ManyToOne(cascade = {CascadeType.PERSIST})
  @JoinColumn(name="BILL_USER_ID")
  private User user;

然后,如果我们要使用session.merge(bill)操作,我们也应该添加CascadeType.MERGE

现在想像,我们有

  @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
  @JoinColumn(name="BILL_USER_ID", insertable = false, updatable = false)
  private User user;

执行上述持久操作后,我们将得到:

SQL> select * from APP_USER;
USER_ID USER_NAME
------- ---------
1       Alex

SQL> select * from APP_BILLING_NUMBER;
BILL_ID BILL_ACCOUNT BILL_BANK_NAME BILL_USER_ID
------- ------------ -------------- ------------
1       EA12345678   BNP Paribas    (null)

您可以看到,两个实体都已插入,但是由于APP_BILLING_NUMBER.BILL_USER_IDnull引用为@JoinColumn(..., insertable = false, ...)。而且由于updatable = false,您无法更新它。

所以,这是一个有效的但非常奇怪的情况。

© www.soinside.com 2019 - 2024. All rights reserved.