如何用jpa映射抽象集合? [英] How to map an abstract collection with jpa?

查看:238
本文介绍了如何用jpa映射抽象集合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图弄清楚是否有可能让JPA在具体实现中坚持抽象集合。



到目前为止,我的代码如下所示:

  @Entity 
公共类报表扩展模型{

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

@MappedSuperclass
public abstract class OpsItem extends Model {

@ManyToOne
Public RetailOpsBranch report;



@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
公共类AItem扩展OpsItem {
...
}

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

但我一直在下面的映射错误上磕磕绊绊,我真的不知道这是否可行? / p>

  JPA错误
发生JPA错误(无法构建EntityManagerFactory):使用@OneToMany或
@ ManyToMany针对未映射的类:models.Report.items [models.OpsItem]

UPDATE



我认为问题不在于抽象类,而在于 @MappedSuperClass 注释。
它看起来像jpa不喜欢与 @MappedSuperClass 映射一对多关系。
如果我将抽象类更改为具体的类,则会出现相同的错误。



如果我再转换到 @Entity 注解,这似乎适用于抽象类和具体类。



使用 @Entity 映射抽象类似乎有些奇怪。
我错过了什么?



解决方案

托管在rhinds的帮助下找出它。
两点需要注意:1)抽象类需要使用@Entity进行注释,以及每个类的表的继承策略以使子类具有它们自己的table。



2)Identity Id的生成在这种情况下不起作用,我不得不使用Table生成类型。

  @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
公开报告报告;
}

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


解决方案

是的,这是可能的。您应该只在顶部抽象类(不会自行保留)上添加MappedSuperClass并在实现类中添加实体注释。



尝试将其更改为某些像这样:

  @MappedSuperclass 
public abstract class OpsItem extends Model {

@ManyToOne
公共RetailOpsBranch报告;
}

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

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

查看hibernate文档的这一部分以获取它的使用细节: http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#d0e1168






更新

对不起,完全错过了每个班级的表格。 Hibernate不支持为每个类的表映射抽象对象(如果所有实现都在一个SQL表中,并且TABLE_PER_CLASS使用每个具体类的表策略,则只能映射List。



限制条件和策略详情如下: http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html_single/#inheritance-limitations


I am trying to work out if it is possible get JPA to persist an abstract collection with concrete implementations.

So far my code looks like this:

@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 {
...
}

But I keep stumbling on the mapping error below and I don't really know if this is feasible?

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

I don't think the problem is with the abstract class but the the @MappedSuperClass annotation. It looks like jpa does not like to map the one to many relationship with a @MappedSuperClass. If I change the abstract class into a concrete class I have the same error.

If I then change to @Entity annotation this seem to work with both the abstract and concrete class.

This seems a bit strange to map an abstract class with @Entity. I'm I missing anything?

SOLUTION

Managed to figure it out with the help from rhinds. Two points to note:

1) the abstract class needs to be annotated with @Entity and inheritance strategy of table per class for the subclasses to have their own table.

2) Identity Id generation will not work in this scenario and I had to use Table generation type.

@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 {
...
}

解决方案

Yep, it is possible. You should only have the MappedSuperClass on the top abstract class (that isnt going to be persisted in itself) and add Entity annotation on the implementation classes.

Try changing it to something like this:

@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 {
...
}

Check this section of the hibernate docs for details on its use: http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#d0e1168


UPDATE

Sorry, completely missed the table per class bit. Hibernate does not support mapping of abstract objects for table per class (can only map List if all implementations are within a single SQL table, and the TABLE_PER_CLASS uses the "table per concrete class" strategy.

Details of limitations and the strategies here: http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html_single/#inheritance-limitations

这篇关于如何用jpa映射抽象集合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆