#java #hibernate #spring #jpa-2.0
#java #переход в спящий режим #spring #jpa-2.0
Вопрос:
Я разрабатываю пример веб-приложения, используя объекты JPA 2.0, Hibernate 3.6.2 и Spring 3. Пример содержит две таблицы в отношениях «один к одному», родительский объект — это Client, а дочерний — Address, PK в адресе ссылается на таблицу Client (идентифицирующую связь).
Выполняя тесты JUnit, я заметил особую проблему с этими двумя сущностями, проблема в том, что дочерняя сущность сохраняется с (ParentID 1), мои сопоставления следующие:
@Entity
public class Client implements Serializable{
private Long clientId;
private Address address;
//Other fields
@Id
@GeneratedValue
public Long getClientId(){return this.clientId;}
public void setClientId(Long id){this.clientId=id;}
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name="clientid",referencedColumnName="fk_clientid")
public Address getAddress(){return this.address;}
}
И дочерний объект:
@Entity
public class Address implements Serializable{
private Long fkClientId;
private Client client;
//Other fields
@Id
@GeneratedValue
public Long getFkClientId(){return this.fkClientId;}
public void setFkClientId(Long id){this.fkClientId=id;}
@OneToOne(mappedBy="address")
public Client getClient(){return this.client;}
}
В моих методах тестирования я связываю оба объекта, используя их установщики, но после сохранения сущностей и выполнения строки:
assertEquals(client.getClientId, client.getAddress().getFkClientId);
Тест завершается неудачей с исключением
java.lang.AssertionError: expected:<654> but was:<655>
Я читал похожие вопросы и проблемы, но почти все они из JPA 1.0, предполагается, что в JPA2.0 общие ключи назначаются автоматически. Чего мне не хватает?
Ответ №1:
Правильная версия такого сопоставления показана в javadoc @OneToOne
. Обратите внимание, что сторона с производным идентификатором должна быть стороной-владельцем отношения (без mappedBy
):
@Entity
public class Client implements Serializable {
@Id
@GeneratedValue
private Long clientId;
@OneToOne(mappedBy = "client", cascade = CascadeType.ALL)
private Address address;
...
}
@Entity
public class Address implements Serializable {
@Id
private Long fkClientId;
@OneToOne
@MapsId
@JoinColumn(name = "fk_clientid")
private Client client;
...
}
Комментарии:
1. Большое вам спасибо! Я запутался на стороне владельца отношений и в том, как это было реализовано в спецификации JPA2.0