Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA多态性单体瘤_Java_Jpa_Polymorphism - Fatal编程技术网

Java JPA多态性单体瘤

Java JPA多态性单体瘤,java,jpa,polymorphism,Java,Jpa,Polymorphism,我不知道如何使用JPA干净地创建一个标记云,其中每个db实体可以有许多标记 例如 Post可以有0个或多个标记 用户可以有0个或多个标记 在JPA中,有没有比让所有实体都子类化为Taggable抽象类更好的方法?其中标记实体将引用多个标记 编辑:标记云只是一个简化我遇到的问题的示例。在我的场景中,关系应该是OneToMany,其中标记不能重用 谢谢为什么不映射一组标记甚至字符串呢 sudocode: @Entity @Table(name="entities") class MyEntity{

我不知道如何使用JPA干净地创建一个标记云,其中每个db实体可以有许多标记

例如

Post可以有0个或多个标记 用户可以有0个或多个标记

在JPA中,有没有比让所有实体都子类化为Taggable抽象类更好的方法?其中标记实体将引用多个标记

编辑:标记云只是一个简化我遇到的问题的示例。在我的场景中,关系应该是OneToMany,其中标记不能重用


谢谢

为什么不映射一组标记甚至字符串呢

sudocode:

@Entity
@Table(name="entities")
class MyEntity{
    long id;
    String someField;
    @ManyToMany(targetEntity=Tag.class)
    @JoinTable(name="entities_to_tags",
         joinColumns={
             @JoinColumn(name="id",  
             referencedColumnName="entity_id",
             inverseJoinColumns={
                 @JoinColumn(name="id", referencedColumnName="tag_id")})
    List<Tag> tags;
    [...getter&setter...]
}

@Entity
@Table(name="tags")
class Tag{
    @Id
    @GeneratedValue
    long id;
    String title;
    [....getter & setter...]
}
@实体
@表(name=“实体”)
类实体{
长id;
字符串字段;
@ManyToMany(targetEntity=Tag.class)
@JoinTable(name=“实体到标记”,
连接柱={
@JoinColumn(name=“id”,
referencedColumnName=“实体\u id”,
反向连接柱={
@JoinColumn(name=“id”,referencedColumnName=“tag\u id”)})
列出标签;
[…getter&setter…]
}
@实体
@表(name=“tags”)
类标签{
@身份证
@生成值
长id;
字符串标题;
[…..getter&setter…]
}

这似乎是多对多,而不是一对多。用户可以有多个标记,并且一个标记可以与多个用户关联

如果您想在标记上与包含每个标记对象的单个集合建立关系,则只需要这样一个超类。是否需要
标记。GetOneGiantCollectionFeveryTaggedentity()
方法

由于标记的对象在其他方面似乎没有任何共同之处,这样的集合在您的应用程序域中真的有任何价值吗?它表面上也可能相当大,并且不是您真正希望通过对象关系处理的东西。从实际角度看,在不了解您的用例的情况下,它似乎像
tag.getTaggedUsers()
tag.getTaggedPosts()
等更有用

抱歉,我想我问的问题比回答的问题多,但不清楚您希望完成的对象域是什么样子:)

编辑:

也许问题的实际答案只是“不,Hibernate不会为您映射一个没有共同祖先的原始类型集合,这些类型碰巧都有实体的外键。”您不必在实体上强加一个“伪”超类,但如果不这样做,则必须创建一个联接表


.?

如果您不需要多态查询,如“get everything tagged Foo”,那么您还可以引入一个新实体(比如
TaggingTarget
),并从
用户创建一个单向一对一关系(
Post
,等等)到
标记目标
以及
标记目标
标记
之间的多对多关系:

@Entity
public class User {
    @OneToOne
    private TaggingTarget target;
    ...
}

@Entity
public class TaggingTarget {
    @ManyToMany(...)
    private Set<Tag> tags;
    ...
}

@Entity
public class Tag {
    @ManyToMany(...)
    private Set<TagTarget> targets;
    ...
}

在JPA中,有没有比让所有实体都子类化为Taggable抽象类更好的方法

让我们忘记这个例子:)JPA确实支持多态关联,但目标类必须是继承层次结构的一部分。下面是关于继承策略的一些经验法则:

  • 单表:
    • 层次结构中的所有类都映射到单个表
    • 此策略提供了良好的支持,可以在 包含以下内容的实体和查询: 整个类层次结构
    • 可能包含某些子类数据的空字段
  • 每类表
    • 层次结构中的每个类映射到一个单独的表,因此提供 对多态性的支持较差 关系
    • 需要对每个子类进行SQL联合或单独的SQL查询
  • 加入
    • 无空字段=>压缩数据
    • 这为多态关系提供了很好的支持,但是 需要一个或多个联接操作- 可能导致性能不佳
简而言之,如果您的子类声明的属性相对较少,则首选
SINGLE_TABLE
策略。如果没有,则使用
JOINED
策略,除非您具有较深的层次结构(在这种情况下,连接的成本可能会比联合的成本更高,然后
TABLE_PER_CLASS
将“不那么糟糕”)

工具书类
  • JPA1.0规范
    • 第2.1.9节“继承”
    • 第2.1.10节“2.1.10继承映射策略”

thx用于回复steve。在您的示例中,标签应包含一个“连接列”对于MyEntity,对吗?如果我有两个可标记的实体,例如MyEntity1和MyEntity2,那该怎么办?就像Aff一样,你可以使用@ManyToMany,这样你就可以得到一个从MyEntity的PKs到Tag的PK.thx的关系表来回复Aff。我给了Tag cloud作为示例来解决这个问题。对不起,这可能不是最好的示例。但理想情况下,我更喜欢OneToMany,因为在我的场景中,“标记”不被重用,我希望避免有额外的联接表。呵呵,我应该在编辑我的答案之前阅读您的评论,然后使用@manyToMany;)
select u from User u where :tag member of u.target.tags
select u from User u join u.target.tags t where t.name = :name