Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Наследоване и JPA


Автор: drG100k 7.11.2008, 22:24
Здравствуйте! 
Во время изучения наследования в JPA возникла такая задача...
Есть 3 таблицы:
1. Parent (EntryId, Number, Description)
2. Child1(Id(FK),etc...)
3. Child2(Id(FK),etc...)
 Между Parent и Child[s] Связи 1:1

Код

//Parent

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.CHAR, length=1)
@Table(name="Parent")
public abstract class Parent {

@Id
@Column(name="EntryId")
protected Long id;

@Column(name="Number")
protected Integer number;

//etc...
}

//Child1
@Entity
@Table(name="Child1")
@DiscriminatorValue(value="A")
@PrimaryKeyJoinColumn(name="Id")
public class Child1 extends Parent {
//etc...
}

//Child2
@Entity
@Table(name="Child2")
@DiscriminatorValue(value="B")
@PrimaryKeyJoinColumn(name="Id")
public class Child2 extends Parent {
//etc...
}


Так вот... Задача состоит в том чтобы поле "Number" по разному заполнялось в зависимости от типа потомка (к примеру если создаётся запись Child1, то поле Number заполняется из Sequence в Базе данных, а если Child2, то
Код

Child2 a = new Child2();
a.setNumber(1);
(EntityManager)em.persist(a);
 

в  @Column есть свойство Insertable, но как значение этого свойства изменять в зависимости от типа потомка?

Пока это писал придумал ещё одну задачку на ту же тему: Наследование на основе одной таблицы. В ней есть поле (не ключевое), которое должно автоматом заполняться, но из разных Sequence, в зависимости от DiscriminatorValue.

Конечно, тут можно в родительском классе на поле поставить Insertable=false и реализовать логику заполнения через триггер в СУБД... 

1. Есть ли решения такого плана с помощью JPA?
2. Как на не ключевое поле "натравить" @GeneratedValue ?
  

Автор: powerOn 7.11.2008, 22:46
а что если в конструкторе Child2 сделать setNumber(1); ?

Автор: drG100k 8.11.2008, 13:39
Цитата(powerOn @ 7.11.2008,  22:46)
а что если в конструкторе Child2 сделать setNumber(1); ?

Так это тоже самое, что я написал: хоть в конструкторе, хоть через setter всё равно придётся использовать механизмы СУБД, а именно триггер before insert. Мне же хочется переложить всё это дело на JPA к примеру 
Код

//Parent   
...
abstract Integer getNumber();
...
//Child1
...
@Column(name="Number", table="Parent")
@GeneratedValue(strategy=SEQUENCE, generator="Child1Generator")
public Integer getNumber(){
return number;
}
...
//Child2
...
@Column(name="Number", table="Parent")
public Integer getNumber(){
return number;
}
...


Но генераторы только на @Id действуют... 
или я где-то что-то недочитал...

Автор: powerOn 8.11.2008, 16:03
Применить @GeneratedValue можно только совместно с @Id, т.е. только для генерации primary ключей. 
Как вариаент, можно для каждого подкласса написать callback на persist операцию (@PrePersist), который подставит нужно значение при сохранении объекта в БД. Но я не могу оценить насколько он Вам подходит...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)