Java ORM: Множественное (интерфейсное) наследование

Я хотел бы сопоставить модель предметной области с реляционной базой данных, используя одну из структур ORM для Java. К сожалению, ни один из них не имеет адекватной поддержки классов, реализующих несколько интерфейсов. Скажем, я хочу отобразить что-то вроде:

public interface Quotable {
}

public interface Tradable {
}

// StockIndex only implements Quotable as it cannot be trade directly
public class StockIndex implements Quotable {
}

// Stock implements both interfaces as there are market quotes and can be traded
public class Stock implements Quotable, Tradable {
}

public class Quote {
    private Quotable quotable;
}

public class Trade {
    private Tradable tradable;
}

Итак, чего я пытаюсь добиться, так это того, что Quote может ссылаться на любой Quoteable (Stock, StockIndex и другие), в то время как Trade может ссылаться только на торгуемые объекты. Я пробовал OpenJPA и (обычный) Hibernate безуспешно, хотя поддержка интерфейсов последнего выглядела многообещающе.

Существует ли какая-либо структура, которая может справиться с моим сценарием? Или есть веские причины, по которым это не следует сопоставлять с базой данных? Если да, то как изменить мою модель?

Мое первоначальное сопоставление Hibernate выглядело примерно так (я не показываю никаких материалов OpenJPA, так как он не поддерживает наследование интерфейса, или, по крайней мере, я не мог понять, как):


    
        
            
        

        

        
            
                
                
            
        

        
            
                
                
            
        
    

Это в значительной степени идентично пример в документации Hibernateи приводит к таблице quotableс идентификатором и столбцом строкового дискриминатора, таблице stock_indexс идентификатором и именем индекса и таблица stockс идентификатором и названием акции. Пока все хорошо...

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

В любом случае, двойное сопоставление Stock не будет хорошим решением, поскольку приложению придется запоминать добавление экземпляров Stock дважды — по одному разу для каждого интерфейса. Я бы предпочел, чтобы фреймворк обрабатывал это автоматически.

В идеале Hibernate позволял бы расширять несколько интерфейсов, т.е.что-то вроде (обратите внимание на атрибут extendsв элементе subclass):


    
        
        
    

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

Как насчет других фреймворков? Я слышал, что EclipseLink также имеет некоторую поддержку интерфейсов, но она плохо документирована.

7
задан kaiboy 2 April 2012 в 19:32
поделиться