2016-08-20 220 views
0

一些领域我有两个实体与多对一(一对多)的关系。JPA实体之间的关系。如何使实体从DB只从关系表

类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类中的名字,而不是ParserEntity列表。

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

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

+0

它节省了您的模型(如所有JPA文档所述)。修正你的模型,让你有一个字符串集合,并填充它。 –

+0

我试图创建没有“mappedBy”和“targerEntity”参数的OneToMany字段。我做了一个集合保存字符串参数,但是编译器告诉OneToMany属性值类型不应该是“String” – Andrey

+0

显然'@ OneToMany'不应该用于...这是关系。你想要存储需要'@ ElementCollection'的字符串集合!建议您阅读JPA教程,其中解释了这些概念 –

回答

0

他们有一个领域的关系,一切似乎没问题。然而,我会 像一个ParserTypeEntity类,以保存ParserEntity 类中的名称在一个单独的集合字段而不是ParserEntity列表中。

我希望在从DB获取类型 时自动填充它们,就像现在使用ParserEntity对象一样。

我不认为你可以使用转换器与集合的关系。
此外,即使你可以,我也不会使用它,因为它可能会使代码更自然,更不可读。对于一个枚举,它是有用的和整体的外观,但对于实体收集,它看起来像一个黑客,因为它打破了实体之间的ORM关系。

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

这个想法是保持你的实际映射,并添加一个你想要的数据的瞬态列表,当ParserTypesEntity加载时,这些数据将以自动方式填充。

因此,在ParserTypesEntity中,您可以添加一个挂钩方法来在实体加载时执行处理。在这种方法中,您可以收集parserEntity收藏的名称并将其添加到transient List<String>

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

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

我正在使用JPA/EntityManager并且您的解决方案看起来很有趣,但它仍然需要从DB中下载所有的parserEntities,我试图避免这种方式(我已经改变了抓取到LAZY类型而不是EAGER)。我要求这样的事情,因为此时应用程序只需要DB中所有实体的名称。它需要一些对象,稍后从数据库中获取,但是在90%的使用率中不需要所有的对象。 – Andrey