Как отобразить реферативную коллекцию с помощью jpa? - PullRequest
9 голосов
/ 26 марта 2012

Я пытаюсь выяснить, можно ли заставить JPA сохранять абстрактную коллекцию с конкретными реализациями.

Пока мой код выглядит так:

@Entity
public class Report extends Model {

    @OneToMany(mappedBy = "report",fetch=FetchType.EAGER)
    public Set<Item> items;
}

@MappedSuperclass
public abstract class OpsItem extends Model {

    @ManyToOne
    public RetailOpsBranch report;
}


@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class AItem extends OpsItem {
...
}

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class BItem extends OpsItem {
...
}

Но я все еще спотыкаюсь об ошибке отображения ниже, и я действительно не знаю, возможно ли это?

JPA error
A JPA error occurred (Unable to build EntityManagerFactory): Use of @OneToMany or
@ManyToMany targeting an unmapped class: models.Report.items[models.OpsItem]

UPDATE

Не думаю, что проблема в абстрактном классе, а в аннотации @ MappedSuperClass . Похоже, что jpa не любит отображать отношения один ко многим с @ MappedSuperClass . Если я изменяю абстрактный класс на конкретный класс, у меня возникает та же ошибка.

Если я затем изменю на аннотацию @ Entity , это, похоже, будет работать как с абстрактным, так и с конкретным классом.

Кажется немного странным сопоставлять абстрактный класс с @ Entity . Я что-то упустил?

РЕШЕНИЕ

Удалось выяснить это с помощью шкуры. Два замечания:

1) абстрактный класс необходимо аннотировать с помощью @Entity и стратегии наследования таблицы для каждого класса, чтобы подклассы имели свою собственную таблицу.

2) Генерация идентификатора не будет работать в этом сценарии, и мне пришлось использовать тип генерации таблицы.

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class OpsItem extends GenericModel {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    public Long id;

    public String          branchCode;

    @ManyToOne
    public Report report;
}

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class AItem extends OpsItem {
...
}

1 Ответ

6 голосов
/ 26 марта 2012

Да, это возможно.Вы должны иметь только MappedSuperClass в верхнем абстрактном классе (который не будет сохранен сам по себе) и добавить аннотацию Entity для классов реализации.

Попробуйте изменить его на что-то вроде этого:

@MappedSuperclass
public abstract class OpsItem extends Model {

    @ManyToOne
    public RetailOpsBranch report;
}

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class AItem extends OpsItem {
...
}

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class BItem extends OpsItem {
...
}

Проверьте этот раздел документации гибернации для получения подробных сведений об его использовании: http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#d0e1168


ОБНОВЛЕНИЕ

Извините, полностью пропущена таблица для каждого бита класса,Hibernate не поддерживает отображение абстрактных объектов для таблицы по классу (может отображать List, только если все реализации находятся в одной таблице SQL, а TABLE_PER_CLASS использует стратегию «таблица на конкретный класс».

Подробности ограничений истратегии здесь: http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html_single/#inheritance-limitations

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...