2015-08-04 6 views
1

У меня есть проект с частью структуры данных, созданной с помощью @Inheritance (strategy = InheritanceType.JOINED). Та часть структуры данных выглядит следующим образом:Hibernate JPA Наследование Наследование

enter image description here

Конструкция основана на мысли in this article. я использую Hibernate с JPA2 интерфейсом, как мой datalayer. Структура выше, привело к следующим POJO/классы DAO (геттеры и сеттер опущены):

BaseItem:

@Entity 
@Table(name = "base_item") 
@Inheritance(strategy = InheritanceType.JOINED) 
public class BaseItemPojo { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id") 
    private Long id; 
} 

PhysicalItem:

@Entity 
@Table(name = "physical_item") 
public class PhysicalItemPojo extends BaseItemPojo{ 
} 

SomeHardware:

@Entity 
@Table(name = "some_hardware") 
public class SomeHardwarePojo extends PhysicalItemPojo{ 
} 

SomeOtherHardware:

@Entity 
@Table(name = "some_other_hardware") 
public class SomeOtherHardwarePojo extends PhysicalItemPojo{ 
} 

Вот мой вопрос:

Один из моих таблиц имеет ссылку на класс base_item, и это сделало бы мою жизнь намного проще, если загружен этот класс либо «some_hardware» или «some_other_hardware "на основе этого base_item_id. Таким образом, я сделал навигационные свойства, как это на этом конкретном классе:

@Entity 
@Table(name = "some_navigation_class") 
public class SomeNavigationClassPojo{ 
    @ManyToOne(optional = false) 
    @JoinColumn(name="base_item_id", insertable = false, updatable = false) 
    private BaseItemPojo baseItem; 

    @ManyToOne 
    @JoinColumn(name="base_item_id", insertable = false, updatable = false) 
    private PhysicalItemPojo physicalItem; 

    @ManyToOne() 
    @JoinColumn(name = "base_item_id", insertable = false, updatable = false) 
    private SomeHardwarePojo someHardwarePojo; 

    @ManyToOne() 
    @JoinColumn(name = "base_item_id", insertable = false, updatable = false) 
    private SomeOtherHardwarePojo someOtherHardwarePojo; 
} 

Как вы уже догадались, выше не работает. Если я пытаюсь получить доступ к «SomeNavigationClassPojo», который имеет родственный «SomeHardwarePojo», прикрепленный к сущности, я получаю следующее сообщение об ошибке:

java.lang.IllegalArgumentException: Can not set SomeOtherHardwarePojo field SomeNavigationClass.someOtherHardware to SomeHardwarePojo.

Для справки, моя цель состоит в том, что если либо someHardwarePojo или someOtherHardwarePojo не существует в базе данных, они просто должны быть установлены в нуль, и не пытался быть сопоставлены с соответствующим другим ребенком PhysicalItemPojo

+0

Почему вы не можете использовать атрибут 'baseItem' и предлагать все остальные как« getters », например, 'getSomeHardwarePojo() {возвращать экземпляр baseItem SomeHardwarePojo? (SomeHardwarePojo) baseItem: null; } '? –

+0

Это отличная идея! Я сразу же попробую. – MichaelCleverly

+0

@Tobias. Оно работало завораживающе. Если вы хотите разработать свой комментарий в качестве ответа, с небольшим примером кода, чтобы другие могли видеть, я с радостью принимаю его как ответ. – MichaelCleverly

ответ

1

Вы можете добавить атрибуты, как простые геттеры:

public class SomeNavigationClassPojo { 
    ... 
    public SomeHardwarePojo getSomeHardwarePojo() { 
     return baseItem instanceof SomeHardwarePojo ? (SomeHardwarePojo) baseItem : null; 
    } 
    ... 
} 

Основной недостаток: Вы можете Использовать атрибут utes в запросе JPA - например, что-то вроде SELECT n FROM SomeNavigationClassPojo n JOIN n.somehardwarepojo s WHERE s.propertyOfHardwarePojo = 'x' невозможно.

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