2013-08-01 6 views
2

Можно ли использовать как @JoinColumn, так и @Column для того же поля в JPA, включив обновления из обоих?JPA, Combine @JoinColumn и @Column

Допустим, у меня есть объект вроде этого:

@Entity 
public class Person{ 
    @JoinColumn(name = "address_id", referencedColumnName = "id") 
    @ManyToOne 
    private Address address; 

    // getters and setters 
} 

Предполагая, что объект Address уже существует - при создании этого объекта, мне нужно, чтобы извлечь адрес из базы данных, прежде чем сохраняющиеся человека. Это мой текущий дизайн во всем моем приложении, но это может вызвать проблемы с производительностью. Можно ли добавить возможность сохраняться только с использованием идентификатора, сохраняя при этом возможность сохраняться с реальным объектом (для того, чтобы не менять большое количество кода в другом месте)? Что-то вроде этого

@Entity 
public class Person{ 
    @JoinColumn(name = "address_id", referencedColumnName = "id") 
    @ManyToOne 
    private Address address; 

    @Column(name="address_id") 
    private Integer addressId; 

    // getters and setters 
} 

em.persist(new Person(1)); 
em.persist(new Person(getAddress(1))); 

Можно ли аннотировать, чтобы разрешить обе эти устойчивые линии? Мое настоящее убеждение состоит в том, что одно из полей должно быть insertable = false

+0

Я не совсем понимаю ваш вопрос. Столбец и JoinColumn - это только аннотации для определения имен и атрибутов столбцов базы данных, никакое отношение не определяется этим. Мой первый вопрос был бы, возможно ли, что адрес используется более чем одним человеком? или имеет адрес одного человека, и если два человека живут по тому же адресу, адрес получает redudant? В любом случае, вы должны использовать аннотацию OneToMany или OneToOne, чтобы определить связь между вашим человеком и вашим адресом, и когда вы определяете каскадирование только для обновления, сохранение или слияние с человеком никогда не создадут адрес. –

+0

Извините, забыл ManyToOne-аннотация –

+0

ваше последнее предположение верно, одно из полей должно иметь 'insertable = false', (а также' updatable = false' и 'deletable = false'), так что поле будет просто прочитанным -единственный. –

ответ

3

Такое дублирующее сопоставление невозможно, так как это может привести к конфликтам. Что делать, если вы установили поле address на адрес с идентификатором = X, а затем addressId на другой идентификатор = Y? Что следует учитывать JPA при сохранении? Вот почему вы должны указать его и сделать одно из этих полей insertable=false, updatable=false.

Решение проблемы: EntityManager.getReference() метод. Он возвращает объект «прокси» для данного класса и идентификатора без фактической загрузки его из БД. Таким образом, вы можете установить address ссылку в Person объекта и сохраняются его:

em.persist(new Person(em.getReference(Address.class, 1))); 

Благодаря этому решению не нужен addressId поле вообще.

Смежные вопросы