2011-11-22 2 views
4

Я использую JPA 1.0, так что я ограничен в том, что я могу сделать, но я до сих пор думаю, что это должно быть возможно сделать следующее, однако я не могу заставить его работать ...Hibernate oneToMany Абстрактный класс переопределение ID

Table CustomerA 
    a_id 

Table ProductB 
    a_id 
    b_id 

Table ProductC 
    a_id 
    c_id 

@Entity 
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) 
public abstract class AbstractProduct { 

    @Id 
    @GeneratedValue.... 
    private Long id; 

    private String name; 

@ManyToOne() 
JoinColumn(name="a_id") 
private CustomerA customerA; 

} 

Теперь я хочу создать подкласс, который может более оседлать Id или создать составной ключ, основанный на PK из Table A и ключа производной таблицы ...

@Entity 
@Table(name="ProductB") 
public class ProductB extends AbstractProduct { 

    //@AttributeOverride(name="id", [email protected](name="B_ID") //Can only be used  with MappedSuperClass and also Emmbedded Objects 
    //@Id //cant override the ID Column so that cant go here 
    //PrimaryKeycolumn join not what i want here 
    private Long productB_id; 

    private String productName; 
} 

@Entity 
@Table(name="CustomerA") 
public class CustomerA 
{ 
    @Id 
    @GeneratedValue.... 
    @Column(name="a_id") 
    private Long aId 

    @OneToMany(mappedBy="customerA", cascade=CascadeType.ALL) 
    private Set<AbstractProduct> product; 
} 

Так по существу CustomerA может содержать много продуктов , но это всегда будет только ProductB или ProductC. Как я могу переопределить Id в подклассе, поскольку вы не можете использовать attributeoverride и Entity, и если вы используете @Entity, вы должны указать @Id всякий раз, когда вы укажете @Entity. Я прочитал wiki wiki jpa, и это выглядит довольно сложным и не подходит для этого в JPA 1.0, но мне интересно, не хватает ли чего-то?

ответ

0

Мое предложение состоит в том, чтобы разделить базовый класс между двумя вашими продуктами, чтобы вы могли ссылаться на них как по-одному. В JPA/Hibernate это означает создание общей таблицы, которая будет содержать общие элементы вашего продукта, а именно ссылку на CustomerA.

, как вы можете сделать это с «JOINED» стратегией наследования:

@Inheritance(strategy=InheritanceType.JOINED) 

Недостаток использования этой стратегии является то, может столкнуться с существующей СТРАТЕГИЕЙ «TABLE_PER_CLASS» уже используется в вашем AbstractProduct базового класса .... хотя это может быть подходящим базовым классом для использования. Из того, что я помню, вы не можете смешивать стратегии наследования.

Вот пример:

@Entity 
@Table(name="CustomerA") 
public class CustomerA 
{ 
    @Id 
    @GeneratedValue.... 
    @Column(name="a_id") 
    private Long aId 

    @OneToMany(mappedBy="customerA", cascade=CascadeType.ALL) 
    private Set<AbstractProduct> product; 
} 

@Entity 
@Table(name="ProductB") 
public class ProductB extends AbstractProduct { 

    private String specificProductBValue; 
} 

@Entity 
@Table(name="ProductC") 
public class ProductC extends AbstractProduct { 

    private String specificProductCValue; 
} 

@Entity 
@Inheritance(strategy=InheritanceType.JOINED) 
public abstract class AbstractProduct { 

    @Id 
    @GeneratedValue.... 
    private Long id; 

    private String name; 

    @ManyToOne() 
    JoinColumn(name="customer_id") 
    private CustomerA customerA; 

} 

Похоже, вы почти там с вашим примером, просто нужно использовать правильную стратегию наследования.

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

Надеюсь, что это поможет.

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