如何使用ORACLE数据库插入JPA OneToOne关系?

时间:2015-03-26 17:13:05

标签: oracle jpa one-to-one

我遇到了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]

感谢您提供任何帮助。
最好的问候。

1 个答案:

答案 0 :(得分:1)

从表中删除任何触发器 - JPA将为您完成所有操作。仔细阅读有关通过序列生成主键值的信息。