从数据库向导 jpa 2.1 @ManyToMany 创建实体,不需要修复列表

Posted

技术标签:

【中文标题】从数据库向导 jpa 2.1 @ManyToMany 创建实体,不需要修复列表【英文标题】:create entity from database wizard jpa 2.1 @ManyToMany, fix list not needed 【发布时间】:2016-05-07 17:55:49 【问题描述】:

我有一些像 multimedia_feature 这样的连接表。

向导将在 Multimedia 类中创建一个 List 属性:

...
@JoinTable(name = "multimedia_feature", joinColumns = 
   @JoinColumn(name = "feature_oid", referencedColumnName = "oid"), inverseJoinColumns = 
   @JoinColumn(name = "multimedia_oid", referencedColumnName = "oid"))
@ManyToMany
private List<Feature> featureList;
...

因为我只需要一个多对一关系(一个功能可以有多个多媒体文件),我将 media_oid 标记为唯一。 在此之后,向导创建其他 2 个表(我认为是多余的)

@Entity
@Table(name = "multimedia_feature")
@XmlRootElement
@NamedQueries(
    @NamedQuery(name = "MultimediaFeature.findAll", query = "SELECT m FROM MultimediaFeature m"),
    @NamedQuery(name = "MultimediaFeature.findByMultimediaOid", query = "SELECT m FROM MultimediaFeature m WHERE m.multimediaFeaturePK.multimediaOid = :multimediaOid"),
    @NamedQuery(name = "MultimediaFeature.findByFeatureOid", query = "SELECT m FROM MultimediaFeature m WHERE m.multimediaFeaturePK.featureOid = :featureOid"))
public class MultimediaFeature implements Serializable 

    private static final long serialVersionUID = 1L;
    @EmbeddedId
    protected MultimediaFeaturePK multimediaFeaturePK;
    @JoinColumn(name = "multimedia_oid", referencedColumnName = "oid", insertable = false, updatable = false)
    @OneToOne(optional = false)
    private Multimedia multimedia;
    @JoinColumn(name = "feature_oid", referencedColumnName = "oid", insertable = false, updatable = false)
    @ManyToOne(optional = false)
    private Feature feature;
...
...

@Embeddable
public class MultimediaFeaturePK implements Serializable 

    @Basic(optional = false)
    @NotNull
    @Column(name = "multimedia_oid")
    private int multimediaOid;
    @Basic(optional = false)
    @NotNull
    @Column(name = "feature_oid")
    private int featureOid;
    ...
    ...

最后它在多媒体类中添加了一个属性:

....
@OneToOne(cascade = CascadeType.ALL, mappedBy = "multimedia")
    private MultimediaFeature multimediaFeature;
....

因为我有很多加入类,我会避免创建所有这些类。 我可以手动创建属性吗,例如:

@JoinTable(name = "multimedia_feature",
           @JoinColumn(name"feature_oid", referencedColumnName = "oid")
)
    @OneToOne(optional = false)
    private Feature feature;

或者这会妨碍正确的持久性?

【问题讨论】:

【参考方案1】:

看起来Multimedia类中的feature属性应该是@ManyToOne关系。 默认情况下,为多对多关系和单向一对多关系的映射创建连接表。 如果你想避免加入类,我认为你可以像这样使用@JoinTable 来映射要素类中的多媒体属性:

@OneToMany
@JoinTable(name = "multimedia_feature",
    joinColumns = @JoinColumn(name = "feature_oid"),
    inverseJoinColumns = @JoinColumn(name = "multimedia_oid") )
private List<Multimedia> multimediaList;

如果您确实需要与连接表的双向关系,映射将是这样的:

public class Feature implements Serializable 
    @OneToMany(mappedBy="feature")
    private List<Multimedia> multimediaList;
    ...


public class Multimedia implements Serializable 
    @ManyToOne
    @JoinTable(name = "multimedia_feature",
            joinColumns = @JoinColumn(name = "multimedia_oid") ,
            inverseJoinColumns = @JoinColumn(name = "feature_oid"))
    private Feature feature;
    ...

或者您可以通过在多媒体表中引入一个连接列(如 feture_oid)来完全删除具有双向关联的连接表。以便您可以轻松映射多媒体类中的特征属性:

@ManyToOne
@JoinColumn(name = "feature_oid")
private Feature feature;

在 Feature 类中会是这样的:

@OneToMany(mappedBy="feature")
private List<Multimedia> multimediaList;

【讨论】:

我不能在多媒体中添加属性,因为这个类有其他类与其他类的连接表......如果我为每个类添加一个属性,我会有很多“空”值在分贝...我认为这不是一个好习惯,对吧?那么,第一种方式,多媒体课我要写什么? @ManyToOne(由多媒体列表映射) ? @Marco 如果您确实需要保留连接表和双向键,那么您可以使用 Multimedia 作为拥有方并在那里定义连接,并在另一端使用 mappedBy 属性,即特征。我调整了我的答案来演示。

以上是关于从数据库向导 jpa 2.1 @ManyToMany 创建实体,不需要修复列表的主要内容,如果未能解决你的问题,请参考以下文章

JPA 2.1在sql server中调用存储过程

Spring Boot 2.1 缺少多个 org.hibernate.jpa.event 类

将 JPA 2.1 中的 List 或 Set 用于同一个表中的多个列

JPA 2.1 Eager Fetch 属性

哪个版本的hibernate支持jpa 2.1?

您将如何使 JPA 2.1 模块独立于 JPA 实现?