2012-06-26 3 views
2

Привет, я хочу иметь отношение один к одному для одного из моих проектов, но Список никогда не заселен.@OneToMany отношение, когда цель имеет составной ключ?

У меня есть класс родительского источника

@Entity 
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) 
public class ParentJob { 
    @Id 
    @Column(name = "ID") 
    int id; 
} 

ребенок

@Entity 
public class TakeJob extends ParentJob { 
    @OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.REMOVE) 
    @JoinColumn(name="FK_JOBID", referencedColumnName="ID") 
    private List<JobRelation> jobRelations; 
} 

и целевой объект

@Entity 
public class JobRelation { 
    @EmbeddedId 
    private JobRelationPK JobRelationPK; 
} 

с ПК

@Embeddable 
public class JobRelationPK implements Serializable { 
    private long fkSomething; 
    @Column(name = "FK_JOBID") 
    private long fkJobId; 
} 

Теперь, поскольку я сказал, что List не заполняется, если я обращаюсь к нему. Меня особенно интересует синтаксис JoinColumn, поскольку на самом деле не имеет значения, что я написал для «имени», даже если это полный мусор. Как я должен обратить внимание на то, что я положил там, или я могу просто поставить «Name =„COLUMN_NAME_IN_JOBRELATION“»

Edit: Я использую EclipseLink 2.3.2

ответ

1

Вы должны сначала быть последовательными, где вы проложите ваши аннотации в иерархии сущностей. Всегда кладите их на поля или всегда кладите их на геттеры. Аннотации на ваших геттерах игнорируются, потому что аннотация @Id помещается в поле id.

После того, как это исправлено, name в @JoinColumn должно быть именем ... столбца объединения. Таким образом, это должно быть имя столбца в таблице JobRelation, которое является внешним ключом таблицы TakeJob.

+0

У меня есть они на геттерах, но я не хочу загромождать свой пример. Похвалил его во втором. У меня изначально было имя, как вы сказали, но это не сработало. Поэтому я задавался вопросом, связано ли это с составным ключом. –

3

Проблема, вероятно, связана с тем, как вы ожидаете установить поле «FK_JOBID» таблицы JobRelation.

Способ, которым вы его сопоставили, может быть доступен для записи через как встроенный атрибут fkJobId для JobRelationPK, так и сопоставление JobRelations в приложении TakeJob. Если вы только устанавливаете его в объекте JobRelation, тогда коллекция TakeJob будет отображать только изменения при обновлении - JPA требует, чтобы вы поддерживали отношения, чтобы они соответствовали тому, что находится в базе данных. Это означает, что вы все равно должны добавить JobRelation в коллекцию TakeJob, чтобы ссылка была синхронизирована с тем, что находится в базе данных, или обновите ее после совершения изменения.

Но поскольку у вас есть два сопоставления с этим полем, столбец соединения должен быть установлен только для чтения, чтобы избежать проблем с записью.

Лучшим решением могло бы стать установление отношения ManyToOne в JobRelation к TakeJob, а затем сопоставление JobRelations для TakeJob, которое должно отображаться этим новым сопоставлением (вместо использования joincolumn). Если вы используете JPA 2.0, вы можете указать новое сопоставление как @MapsId («fkJobId»). что-то вроде:

@Entity public class JobRelation { 
    @EmbeddedId 
    private JobRelationPK JobRelationPK; 
    @ManyToOne 
    @MapsId("fkJobId") 
    private TakeJob job; 
} 

Это позволит встроенный fkJobId атрибут должен быть установлен на значение из ссылочного TakeJob Id при вставке.

+0

"или обновить его после совершения изменения. Достаточно ли вызвать' em.clear() 'before или' em.refresh() 'после того, как я посмотрел элемент вверх? –

+0

В основном я сохраняю новое JobRelation с JobRelationPK.и когда я делаю это, у меня нет объекта TakeJob. Поэтому я не могу вручную добавить его в код. –

+0

Также я думал, что это точка JPA, поэтому мне не нужно заботиться о том, где/когда JobRelations добавлены, но будут иметь их в TakeJob в зависимости от данных в базе данных. Мой пример отлично работает, когда я добавляю их вручную на Java, но тогда мне не нужны аннотации '@ OneToMany' –

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