2016-04-23 79 views
0

我有一个名为Profile的实体,它的主键实际上应该是指向RegisteredUser的外键。将约束外键添加到JPA中的实体

目前,这就是我想说的是,在Profile场既是它的主键和外键引用RegisteredUser

@Id 
@OneToOne 
@JoinColumn(foreignKey = @ForeignKey(name = "REGISTERED_USER_FK")) 
private RegisteredUser registeredUser; 

,并在RegisteredUser实体,我有以下几点:

@OneToOne(cascade = CascadeType.ALL, mappedBy = "registeredUser") 
private Profile profile; 

不幸的是,当我运行SpringBootApplication,我有以下错误:

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'registered_user_username' cannot be null 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_40] 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_40] 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_40] 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422) ~[na:1.8.0_40] 
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:404) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
    at com.mysql.jdbc.Util.getInstance(Util.java:387) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:932) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
    at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
    at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
    at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5094) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994) ~[mysql-connector-java-5.1.38.jar:5.1.38] 
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
    ... 42 common frames omitted 

当我尝试运行此代码:

User user = new User("blah"); 
repo.save(user); // using repositories to store entities to the db 

Profile profile = new Profile(user.getFirstName()); 

RegisteredUser rUser = new RegisteredUser(user.getUsername(), profile); 
rur.save(rUser); 

我检查,看看用户的用户名是空的,但它不是......问题是,当我保存rUser ...

+1

列'registered_user_username'属于哪个实体,'RegisteredUser'? – aribeiro

+0

为什么要从用户分离配置文件?没有用户对象可以配置文件吗? – WeMakeSoftware

+0

@aribeiro没有这样的专栏。我在'RegisteredUser'中有一个名为'username'的字段,它也应该是'RegisteredUser'的主键,但也应该是一个引用'User'主键的外键...... – nbro

回答

1

根据JPA spec,您不能使用@Id注释标注RegisteredUser

我无法想象为什么你需要从用户单独的配置文件,但如果你真的需要的话,你有几种选择:

选项A:

使用@Embeddable注释上Profile。您不会为Profile实体获得单独的表格,但您将在Java中获得单独的对象。

选项B:

Profile使用@ManyToOne。因此,用户的生命周期将是这样的:

  • 创建用户
  • 创建简历
  • 保存配置文件
  • 设置用户的配置文件来保存的配置文件
  • 保存用户

你甚至可以在这些对象上具有相同的主键(查找建议here

选项C:

配置@OneToOne,但忘了具有具有相同的主键两个实体的要求。