我遇到了JPA OneToOne关系的问题,我花了4天的时间尝试解决它,但没有成功。
首先,看到oracle不支持Generate.Auto作为主键,我们必须在插入前使用序列创建触发器。
这是我的两张桌子:
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)
)
以及instertions的触发器:
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]
感谢您提供任何帮助。
最好的问候。
答案 0 :(得分:1)
从表中删除任何触发器 - JPA将为您完成所有操作。仔细阅读有关通过序列生成主键值的信息。