2010-11-17 3 views
6

Я проходил несколько сообщений в Stackoverflow на JPA, и я читал несколько мест, в которых JPA не поддерживает интерфейсы. Может кто-то может поделиться тем, что это означает в реальном проекте. Означает ли это, что мы не можем аннотировать интерфейс?JPA не поддерживает интерфейсы.

ответ

11

Это означает, что вы не можете сопоставлять (аннотировать) или запрашивать на поверхности. Вы можете запрашивать только классы @Entity, и их можно разместить только на реальных классах, а не на интерфейсах. Обычно это не проблема, интерфейс не имеет состояния, поэтому это не то, что действительно актуально для сохранения на протяжении большей части времени. Вы все еще можете использовать интерфейсы в своей модели, вы просто не можете напрямую их сопоставлять.

Если у вас есть отношения, которые используют тип интерфейса, вам просто нужно установить targetEntity в класс реализации. Если у вас есть несколько исполнителей и не может заставить их делиться наследованием, тогда вам нужно стать более креативными. Некоторые поставщики JPA, такие как EclipseLink, поддерживают интерфейсы.

See, http://en.wikibooks.org/wiki/Java_Persistence/Advanced_Topics#Interfaces

+0

Итак, если у меня есть 1-много от Person to Address, и если может быть много разных типов адресов (например, CanadianAddress, UKAddress и т. Д.), Как мне сопоставить это ? –

+3

Самый простой способ - определить класс AbstractAddress и использовать наследование JPA.В противном случае, если вы используете EclipseLink, вы можете сопоставить это с помощью сопоставления @VariableOneToOne. Вы могли бы также иметь у человека канадский адрес, ukAddress и т. Д. – James

0

Вам нужен прокси-генератор для интерфейса или реализации, которую вы предоставляете.

Можете ли вы опубликовать ссылки на ответы SO, о которых вы думаете, чтобы мы могли получить полный контекст? Это может помочь ответить на вопрос.

+0

Вот один: http://stackoverflow.com/questions/4193676/jpa-relations-and-polymorphism. Можете ли вы рассказать о генераторе прокси или указать мне на какую-то статью в Интернете? –

10

В JPA, use @MappedSuperclass for inheritance, аннотировать абстрактные классы, а не интерфейсы.

Я предпочитаю использовать общие базовые классы для всех моих объектов в данном проекте:

@MappedSuperclass 
public abstract class BaseEntity implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
} 

Теперь скажем, что некоторые из моих образований имеют дополнительное поведение в общем: автоматически обновляется временные метки для createdDate и updatedDate

@MappedSuperclass 
public abstract class ExtendedEntity extends BaseEntity{ 

    @Temporal(TemporalType.TIMESTAMP) 
    private Date createdDate; 

    @Temporal(TemporalType.TIMESTAMP) 
    private Date updatedDate; 

    @PrePersist 
    protected void creationTimeStamp(){ 
     createdDate = new Date(); 
     this.updateTimeStamp(); 
    } 

    @PreUpdate 
    protected void updateTimeStamp(){ 
     updatedDate = new Date(); 
    } 

} 

Теперь некоторые из моих сущностей напрямую распространяют BaseEntity, а другие расширяют ExtendedEntity (если им нужны временные метки).

Вы также можете настроить the way the inheritance is modeled:

  • Одна таблица на иерархии классов
  • таблица на конкретный класс объекта (по умолчанию)
  • «присоединиться к» стратегии А, причем поля или свойства, которые являются специфическими к подклассу сопоставляются с другой таблицей, чем поля или свойства, которые являются общими для родительского класса.

ОТВЕТСТВЕННОСТЬ: Я думаю, что выбор не для того, чтобы поддержка интерфейсов является хорошей. Интерфейсы предназначены для моделирования поведения, а не состояния. JPA - это управление состоянием, а не поведением, поэтому обе концепции не подходят друг другу.

И в тех случаях, когда вы думаете, что вам нужно множественное наследование, perhaps @Embeddable is the solution

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