【问题标题】:jpa unidirectional One-to-Many with a Collection of Abstract type带有抽象类型集合的 jpa 单向一对多
【发布时间】:2016-03-14 22:13:38
【问题描述】:

我在使用 JPA 时遇到问题。基本上,我拥有的是一个具有抽象类型列表的实体,我需要将列表中的每个元素都保存在具有外键(与实体相关)的相应表中。代码如下:

@Entity(name = "entity")
public class Entity{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private BigInteger id;

@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name="entity_id", referencedColumnName="id")
private List<AbstractType> types;
}

抽象类型:

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractType{
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private BigInteger id;

private String someProp;

@Column(name="entity_id")
private BigInteger entityId;
}

A型:

@Entity(name = "type_a")
@Transactional
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class TypeA extends AbstractType{
private String prop1;
private String prop2;
}

B型:

@Entity(name = "type_b")
@Transactional
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class TypeB extends AbstractType{
private String prop3;
private String prop4;
}

我遇到了 SQL 错误。生成的查询尝试更新抽象类型的表(不应该存在)。这是查询的一部分:

update hibernate_sequences set sequence_next_hi_value = ? where 
sequence_next_hi_value = ? and sequence_name = 'abstract_type'
insert into type_a (some_prop, entity_id, prop1, prop2) values (?, ?, ?, ?)
insert into type_b (some_prop, entity_id, prop3, prop4) values (?, ?, ?, ?)
update abstract_type set entity_id=? where id=?

如您所见,它正在尝试更新一个不存在(也不应该)存在的表。 'abstract_type' 表。

提前致谢。

【问题讨论】:

  • 如果某些东西是抽象的,使用@MappedSuperclass 更有意义。继承在根类中指定一次。不需要在子类中重新指定!
  • @Dherik,也许是同样的问题,但该解决方案对我不起作用。这种方法不会将 FK 保存在具体类的表中。
  • @NeilStockton,我知道我应该使用 MappedSuperclass,但这不起作用。那是因为我的列表是那个抽象类型的,它试图找到抽象类型实体,如果你使用那个注释它就不存在了。
  • 您的意思是“它在 Hibernate 中不起作用”?在其他 JPA 实现中也是如此。

标签: java hibernate jpa one-to-many


【解决方案1】:

当然,你不能命名一个类Entity而不引起问题。

您可以通过最小化注释并让 JPA 来完成它的工作,从而使这变得更简单。一个Container 类拥有AbstractTypes 的集合:

@Entity
public class Container {
    @Id @GeneratedValue
    private Long id;

    @OneToMany(cascade=CascadeType.ALL)
    private List<AbstractType> types;

    public List<AbstractType> getTypes() { return types; }
    public void setTypes(List<AbstractType> types) { this.types = types; }
}

AbstractType 就是这样:

@Entity
public abstract class AbstractType {
    @Id @GeneratedValue
    private Long id;
}

还有几个具体类型可以从抽象超类扩展和继承: 编辑:可以使用 ManyToOne 关联添加返回 Container 类的 FK。

@Entity
public class TypeA extends AbstractType {
@ManyToOne
private Container container;

}

还有:

@Entity
public class TypeB extends AbstractType {    
@ManyToOne
private Container container;
}

当我运行 Minimal, Complete, Verifiable Example 时,我得到以下输出:

Hibernate: create table AbstractType (DTYPE varchar(31) not null, id bigint not null, container_id bigint, primary key (id))
Hibernate: create table Container (id bigint not null, primary key (id))
Hibernate: create table Container_AbstractType (Container_id bigint not null, types_id bigint not null)

Hibernate: insert into Container (id) values (?)
Hibernate: insert into AbstractType (container_id, DTYPE, id) values (?, 'TypeA', ?)
Hibernate: insert into AbstractType (container_id, DTYPE, id) values (?, 'TypeB', ?)
Hibernate: insert into Container_AbstractType (Container_id, types_id) values (?, ?)
Hibernate: insert into Container_AbstractType (Container_id, types_id) values (?, ?)
Hibernate: select container0_.id as id1_1_ from Container container0_

model.Container@40591559

【讨论】:

  • 给类Entity命名真的不是问题。为什么 JPA 实现要禁止这样做?!
  • 不同的问题。 "导入 javax.persistence.Entity 与同一文件中定义的类型冲突"
  • 类和属性的名称已更改。 “实体”不是我班级的名字...
  • 我想的也差不多。由于它导致针对 JPA 规范的编译器错误,我想我会将它包含在答案中。
  • 如果我按照您的建议进行操作,我会丢失一个重要字段,即 TypeA 和 TypeB 上的 FK 字段。那是行不通的。如果我把它拿出来,它会起作用。但我需要这个字段。
猜你喜欢
  • 2019-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多