Общий PK при несоответствии сущностей

#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