如果我有这样的配置,它可以工作吗?
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "FOREIGN_ID", nullable = false, insertable = false, updatable = false)
ForeignClass foreignClass;
我不认为,因为级联类型的行为与可插入和可更新的参数冲突。
你怎么看?
答案 0 :(得分: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_ID
,null
引用为@JoinColumn(..., insertable = false, ...)
。而且由于updatable = false
,您无法更新它。
所以,这是一个有效的但很奇怪的情况。
答案 1 :(得分:0)
它们含义不同,彼此不冲突。
因此,给出了以下映射:
@Entity
@Table(name="player")
public class Player {
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "team_id", nullable = false, insertable = false, updatable = false)
Team team;
}
cascade
意味着在EntityManager
上使用persist()
到merge()
或player
时,JPA将自动 也请致电此玩家所在团队的persist()
/ merge()
。
insertable
和updatable
与是否允许分配新团队或为玩家更新团队有关。就数据库表而言,与是否允许插入或更新Player
表的team_id
列的值有关。
所以一个是关于在Team
表中插入/更新记录,而另一个是关于Player
表的team_id
列的值插入/更新,这是完全不同的