【问题标题】:JPA relations between entities. How to make Entity take from DB only some field from relationed table实体之间的 JPA 关系。如何使实体仅从数据库中获取关系表中的某些字段
【发布时间】:2016-12-27 17:29:34
【问题描述】:

我有两个具有多对一(一对多)关系的实体。

类 ParserEntity:

import javax.persistence.*;

@Entity
@Table(name = "parser", schema = "newsmonitoringdb")
public class ParserEntity {
    public ParserEntity() {
    }

    public ParserEntity(String name, SourceTypesEntity type) {
        this.name = name;
        this.type = type;
    }

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;
    @Basic
    @Column(name = "name")
    private String name;

    @ManyToOne(optional = false)
    @JoinColumn(name="type",referencedColumnName="id")
    private SourceTypesEntity type;

    ...//getters, setters and other fields are here
    }
}

类 ParserTypesEntity:

import javax.persistence.*;
import java.util.Collection;
import java.util.List;

/**
 * Created by User on 17.08.2016.
 */
@Entity
@Table(name = "source_types", schema = "newsmonitoringdb")
public class ParserTypesEntity {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;
    @Basic
    @Column(name = "name")
    private String name;

    @OneToMany(mappedBy="type", fetch=FetchType.EAGER, targetEntity = ParserEntity.class)
    private Collection<ParserEntity> siteParser;

    ...//getters and setters are here
    }
}

他们有一个领域的关系,一切似乎都很好。 但是,我希望 ParserTypeEntity 类仅将 ParserEntity 类中的名称保存在单独的 Collection 字段中,而不是 ParserEntity 列表中。

我希望在从数据库中检索类型时自动填充它们,就像现在使用 ParserEntity 对象一样。

有没有办法做到这一点,或者我必须将关系更改为单向关系,获取所有类型,然后通过其 id 获取每种类型的名称?

【问题讨论】:

  • 它保存了您的模型所拥有的内容(正如所有 JPA 文档所说)。修复你的模型,让你有一个字符串集合,然后填充它。
  • 我尝试创建没有“mappedBy”和“targeterEntity”参数的 OneToMany 字段。我做了一个集合保存字符串参数,但是编译器告诉 OneToMany 属性值类型不应该是“String”
  • 显然 @OneToMany 不应该被使用......那是为了关系。你想存储一个字符串集合......这需要@ElementCollection!建议您阅读解释这些概念的 JPA 教程

标签: java mysql jpa foreign-keys mapping


【解决方案1】:

他们有一个领域的关系,一切似乎都很好。不过我会 像 ParserTypeEntity 类只保存来自 ParserEntity 的名称 类放在单独的 Collection 字段中,而不是 ParserEntity 列表中。

我希望在检索类型时自动填充它们 从 DB 中获取的方式与现在处理 ParserEntity 对象的方式相同。

我认为您不能使用转换器来与集合建立关系。
此外,即使你可以,我也不会使用它,因为它会使代码不那么自然和可读性差。对于枚举来说,它很有用,而且总体上是装饰性的,但对于实体集合来说,它看起来像一个 hack,因为它破坏了实体之间的 ORM 关系。

如果您使用JPA/EntityManager,我可以提出一个解决方法:使用实体的生命周期事件。否则,如果你使用 Hibernate/SessionFactory,你应该寻找 Hibernate 的监听器。原理是一样的。

这个想法是保留您的实际映射并添加一个包含您希望的数据的临时列表,当加载 ParserTypesEntity 时,这些数据将以自动方式填充。

所以,在ParserTypesEntity 中,您可以添加一个钩子方法来在实体加载时进行处理。在此方法中,您可以收集parserEntity 集合的名称并将其添加到transient List&lt;String&gt; 中。

public class ParserTypesEntity {
 ...
  @Transient
  private List<String> parserTypeNames;

  @PostLoad
  public void postLoad() {
    parserTypeNames = new ArrayList<>();
    for (ParserEntity parserEntity : siteParser){
      parserTypeNames.add(parserEntity.getName());
   }
  ...
}

【讨论】:

  • 我正在使用 JPA/EntityManager 并且您的解决方案似乎很有趣,但它仍然需要从 DB 下载所有 parserEntities,我试图避免这种情况(我已经将 Fetching 更改为 LAZY 类型而不是渴望)。我需要这样的东西,因为此时应用程序只需要数据库中所有实体的名称。它将需要一些对象,稍后完全从 db 中获取,但在 90% 的使用情况下,它们都不需要。
猜你喜欢
  • 1970-01-01
  • 2021-04-07
  • 1970-01-01
  • 2014-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-04
相关资源
最近更新 更多