如何使用 ORACLE 数据库插入 JPA OneToOne 关系?
How to do insertion with JPA OneToOne relationship using ORACLE database?
我遇到了 JPA OneToOne 关系问题,我花了 4 天时间尝试解决但没有成功。
首先,看到oracle不支持主键Generate.Auto,我们必须在插入前使用序列创建触发器
这是我的 2 个表:
CREATE TABLE address (
ID INTEGER PRIMARY KEY,
CITY varchar(50) DEFAULT NULL,
COUNTRY varchar(50) DEFAULT NULL,
STREET varchar(50) DEFAULT NULL,
SUBURB varchar(50) DEFAULT NULL
)
CREATE TABLE utilisateur (
ID INTEGER PRIMARY KEY,
EMAIL varchar(50) DEFAULT NULL,
FIRSTNAME varchar(50) DEFAULT NULL,
LASTNAME varchar(50) DEFAULT NULL,
PASSWORD varchar(64) DEFAULT NULL,
USERNAME varchar(50) NOT NULL,
ADDRESS_ID INTEGER DEFAULT NULL,
CONSTRAINT FK_USER_ADDRESS_ID FOREIGN KEY (ADDRESS_ID) REFERENCES address (ID)
)
以及插入的触发器:
create SEQUENCE address_seq;
CREATE OR REPLACE TRIGGER address_trig
BEFORE INSERT ON address
FOR EACH ROW
BEGIN
:new.id := address_seq.nextval;
END
create SEQUENCE user_seq
/
CREATE OR REPLACE TRIGGER user_trig
BEFORE INSERT ON utilisateur
FOR EACH ROW
BEGIN
:new.id := user_seq.nextval;
END;
/
实体:
@Entity
@Table(name = "UTILISATEUR")
public class User implements Serializable {
@Id
@SequenceGenerator(name = "USER_SEQ", sequenceName = "USER_SEQ", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_SEQ")
@Column(name = "id", nullable = false)
private Integer id;
@Column(nullable = false, length = 50)
private String username;
@JoinColumn(name = "ADDRESS_ID")
@OneToOne(cascade = {CascadeType.ALL})
private Address address;
@ManyToMany
@JoinTable(name = "user_roles", joinColumns = {
@JoinColumn(name = "User_userid")}, inverseJoinColumns = {
@JoinColumn(name = "Role_roleid")})
private List<Role> roles;
public User() {
roles = new ArrayList<Role>();
address = new Address();
}
@Entity
public class Address implements Serializable {
@Id
@SequenceGenerator(name = "USER_SEQ", sequenceName = "USER_SEQ", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_SEQ")
@Column(name = "id", nullable = false)
private Integer id;
.....
创建方法:
public void create(T t) {
this.em.persist(t);
this.em.merge(t);
}
为了创建新用户,调用此方法:
public void doCreateUser() {
try {
addressService.create(address);
newUser.setAddress(address);
userService.create(newUser);
FacesMessage message = new FacesMessage("utilisateur ajouté avec succès");
FacesContext.getCurrentInstance().addMessage(null, message);
} catch (Exception e) {
....}
使用 MySQL 插入成功,但是当我将池配置为使用 ORACLE 时,我收到一个错误,这意味着违反了外键,我知道在调试时我看到了创建和插入的对象地址进入用户,但在方法结束时我得到这个错误:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: ORA-02291: integrity constraint (FK_USER_ADDRESS_ID) violated - parent key not found
Error Code: 2291
Call: INSERT INTO UTILISATEUR (id, EMAIL, FIRSTNAME, LASTNAME, PASSWORD, USERNAME, ADDRESS_ID) VALUES (?, ?, ?, ?, ?, ?, ?)
bind => [7 parameters bound]
感谢您对此的任何帮助。
最好的问候。
从您的表中删除所有触发器 - JPA 将为您完成所有工作。仔细阅读有关通过序列生成主键值的信息。
我遇到了 JPA OneToOne 关系问题,我花了 4 天时间尝试解决但没有成功。
首先,看到oracle不支持主键Generate.Auto,我们必须在插入前使用序列创建触发器
这是我的 2 个表:
CREATE TABLE address (
ID INTEGER PRIMARY KEY,
CITY varchar(50) DEFAULT NULL,
COUNTRY varchar(50) DEFAULT NULL,
STREET varchar(50) DEFAULT NULL,
SUBURB varchar(50) DEFAULT NULL
)
CREATE TABLE utilisateur (
ID INTEGER PRIMARY KEY,
EMAIL varchar(50) DEFAULT NULL,
FIRSTNAME varchar(50) DEFAULT NULL,
LASTNAME varchar(50) DEFAULT NULL,
PASSWORD varchar(64) DEFAULT NULL,
USERNAME varchar(50) NOT NULL,
ADDRESS_ID INTEGER DEFAULT NULL,
CONSTRAINT FK_USER_ADDRESS_ID FOREIGN KEY (ADDRESS_ID) REFERENCES address (ID)
)
以及插入的触发器:
create SEQUENCE address_seq;
CREATE OR REPLACE TRIGGER address_trig
BEFORE INSERT ON address
FOR EACH ROW
BEGIN
:new.id := address_seq.nextval;
END
create SEQUENCE user_seq
/
CREATE OR REPLACE TRIGGER user_trig
BEFORE INSERT ON utilisateur
FOR EACH ROW
BEGIN
:new.id := user_seq.nextval;
END;
/
实体:
@Entity
@Table(name = "UTILISATEUR")
public class User implements Serializable {
@Id
@SequenceGenerator(name = "USER_SEQ", sequenceName = "USER_SEQ", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_SEQ")
@Column(name = "id", nullable = false)
private Integer id;
@Column(nullable = false, length = 50)
private String username;
@JoinColumn(name = "ADDRESS_ID")
@OneToOne(cascade = {CascadeType.ALL})
private Address address;
@ManyToMany
@JoinTable(name = "user_roles", joinColumns = {
@JoinColumn(name = "User_userid")}, inverseJoinColumns = {
@JoinColumn(name = "Role_roleid")})
private List<Role> roles;
public User() {
roles = new ArrayList<Role>();
address = new Address();
}
@Entity
public class Address implements Serializable {
@Id
@SequenceGenerator(name = "USER_SEQ", sequenceName = "USER_SEQ", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_SEQ")
@Column(name = "id", nullable = false)
private Integer id;
.....
创建方法:
public void create(T t) {
this.em.persist(t);
this.em.merge(t);
}
为了创建新用户,调用此方法:
public void doCreateUser() {
try {
addressService.create(address);
newUser.setAddress(address);
userService.create(newUser);
FacesMessage message = new FacesMessage("utilisateur ajouté avec succès");
FacesContext.getCurrentInstance().addMessage(null, message);
} catch (Exception e) {
....}
使用 MySQL 插入成功,但是当我将池配置为使用 ORACLE 时,我收到一个错误,这意味着违反了外键,我知道在调试时我看到了创建和插入的对象地址进入用户,但在方法结束时我得到这个错误:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: ORA-02291: integrity constraint (FK_USER_ADDRESS_ID) violated - parent key not found
Error Code: 2291
Call: INSERT INTO UTILISATEUR (id, EMAIL, FIRSTNAME, LASTNAME, PASSWORD, USERNAME, ADDRESS_ID) VALUES (?, ?, ?, ?, ?, ?, ?)
bind => [7 parameters bound]
感谢您对此的任何帮助。
最好的问候。
从您的表中删除所有触发器 - JPA 将为您完成所有工作。仔细阅读有关通过序列生成主键值的信息。