具有相同主键和外键双向关系的Hibernate Entity OneToOne

时间:2016-08-10 16:09:57

标签: java mysql hibernate jpa

我有两个表配置和组织表如下:

T_Organization
ID (Primary Key)
Name
Address

T_Configuration
Organization_ID (Primary_Key and Foreign Key)
Name
Some Configs

我通过执行以下操作成功地从Configuration实体添加了单向关系:

@Id
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "organizations_id", referencedColumnName="id")
Organization id;

但是我试图在组织实体内添加一个成员变量,以便我可以从Organization对象访问配置值。

我在尝试:

@OneToOne
@PrimaryKeyJoinColumn
private ConfigurationEntity organizationId;

但是我在启动时遇到以下异常:

[talledLocalContainer] Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'this_.organizationId' in 'field list'
[talledLocalContainer]  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.7.0_79]
[talledLocalContainer]  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) ~[?:1.7.0_79]
[talledLocalContainer]  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.7.0_79]
[talledLocalContainer]  at java.lang.reflect.Constructor.newInstance(Constructor.java:526) ~[?:1.7.0_79]
[talledLocalContainer]  at com.mysql.jdbc.Util.handleNewInstance(Util.java:400) ~[mysql-connector-java-5.1.36.jar:5.1.36]
[talledLocalContainer]  at com.mysql.jdbc.Util.getInstance(Util.java:383) ~[mysql-connector-java-5.1.36.jar:5.1.36]
[talledLocalContainer]  at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:980) ~[mysql-connector-java-5.1.36.jar:5.1.36]
[talledLocalContainer]  at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3847) ~[mysql-connector-java-5.1.36.jar:5.1.36]
[talledLocalContainer]  at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3783) ~[mysql-connector-java-5.1.36.jar:5.1.36]
[talledLocalContainer]  at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2447) ~[mysql-connector-java-5.1.36.jar:5.1.36]
[talledLocalContainer]  at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2594) ~[mysql-connector-java-5.1.36.jar:5.1.36]
[talledLocalContainer]  at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2545) ~[mysql-connector-java-5.1.36.jar:5.1.36]
[talledLocalContainer]  at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1901) ~[mysql-connector-java-5.1.36.jar:5.1.36]
[talledLocalContainer]  at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2002) ~[mysql-connector-java-5.1.36.jar:5.1.36]
[talledLocalContainer]  at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:404) ~[c3p0-0.9.5-pre10.jar:0.9.5-pre10]
[talledLocalContainer]  at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:82) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
[talledLocalContainer]  ... 61 more

我在这里找到了解决方案http://websystique.com/hibernate/hibernate-one-to-one-unidirectional-with-shared-primary-key-annotation-example/

关于我为什么会看到这个的任何建议?

编辑以包含文件:

Organization.java

@SuppressWarnings("serial")
@Entity
@Table(name="t_organization")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@DynamicUpdate
@Indexed
@Data
public class Organization implements Serializable{
    @DocumentId
    @Id @GeneratedValue @Column(name="id")
    private long id;
    @Column(name="name")
    private String name;
    @Column(name="address")
    private String address;
}

ConfigurationEntity.java

@SuppressWarnings("serial")
@Entity
@Table(name = "t_configuration")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@DynamicUpdate
@Data
public class Configuration implements Serializable {
    @Id
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "organization_id", referencedColumnName="id")
    Organization id;

    @Column(name = "name")
    String name;
}

编辑:编辑:解决方案: Organization.java

@SuppressWarnings("serial")
@Entity
@Table(name="t_organization")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@DynamicUpdate
@Indexed
@Data
public class Organization implements Serializable{
    @DocumentId
    @Id @GeneratedValue @Column(name="id")
    private long id;
    @Column(name="name")
    private String name;
    @Column(name="address")
    private String address;

        @Getter
@Setter
@OneToOne(mappedBy="organization", fetch = FetchType.LAZY, orphanRemoval=true)
private ConfigurationEntity configurationEntity;
}

ConfigurationEntity.java

@SuppressWarnings("serial")
@Entity
@Table(name = "t_configuration")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@DynamicUpdate
@Data
public class Configuration implements Serializable {
@Id
@Column(name="organizations_id")
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign",parameters=@Parameter(name="property", value="organization"))
long id;

@OneToOne
@PrimaryKeyJoinColumn
private Organization organization;

@Column(name = "name")
String name;
}

1 个答案:

答案 0 :(得分:1)

  

但是我试图在组织实体中添加一个成员变量,以便我可以从Organization对象访问配置值。

要做到这一点,您需要做的是按照以下方式实现双向一对一关系:

public class Organization implements Serializable{
    @Id @GeneratedValue @Column(name="id")
    private long id;

    private String name;
    private String address;

    @OneToOne(mappedBy = "id")
    private Configuration configuration;

   // getters + setters
}