Hibernate,在多对多连接中使用常量

Hibernate, Use a constant in a many to many join

我有一个多对多连接,我正尝试在 Hibernate 中使用以下 tables;

CREATE TABLE media (
   id INTEGER NOT NULL AUTO_INCREMENT,
   name VARCHAR(100) NOT NULL ,
   file longblob COMMENT 'Content of the file if it is embedded',
   PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;

CREATE TABLE media_reference (
  id INTEGER NOT NULL AUTO_INCREMENT,
  media_id INTEGER NOT NULL COMMENT 'ID of the media',
  reference_id INTEGER DEFAULT NULL,
  reference_type VARCHAR(40) DEFAULT NULL,
  PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;

CREATE TABLE people (
  id INTEGER NOT NULL AUTO_INCREMENT,
  name VARCHAR(250) NOT NULL,
  reference_type VARCHAR(40) DEFAULT 'People',
  PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;

基本上,人物记录可以链接到许多媒体记录,媒体记录可以链接到许多人物记录。

我在 'media_reference' table 中使用了 'reference_type' 字段来存储关系所属的 table 的名称,因为我希望能够使用相同的机制将媒体记录与其他 table 中的记录相关联。 reference_type 和 reference_id 的组合用于获取 media_reference 条记录。

我花了几天的时间在原地打转,尝试各种方法让它发挥作用。我对 Hibernate 很陌生,所以我什至不确定要问什么问题,因此我花了很长时间才找到前进的方向。

下面的代码可以按照我想要的方式工作。当我更新或创建它们时,我可以将媒体记录添加到人员记录中。我不喜欢代码的一点是需要在 people table 中有一个 reference_type 字段。这是因为它总是相同的,但我无法找到任何其他方法将 table 的名称输入 media_reference.reference_type 字段。

理想情况下,在 PeopleEntity 的 @ManyToMany 注释中 class 我可以为 reference_type @JoinColumn 指定一个常量,但据我所知你不能在加入列。

所以基本上我希望能够使用常量值作为连接的一部分进行多对多连接。或者,如果有另一种方法来完成整个事情,我愿意接受任何建议。

提前致谢。

保罗

密码

PeopleEntity.java

package com.company.system.hibernate.entities;

import javax.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

@Entity
@Table(name = "people")
public class PeopleEntity implements Serializable {

    private static final long serialVersionUID = 4550422780535557785L;

    private String name;
    private Set<MediaEntity> media = new HashSet<MediaEntity>(0);
    private Integer id;
    private String referenceType = this.getClass().getSimpleName();

    @Column(name = "id", nullable = false, length = 10, precision = 0)
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Basic
    @Column(name = "name", nullable = false, insertable = true, updatable = true, length = 250)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable (name = "media_reference",  joinColumns = {
            @JoinColumn(name="reference_id", referencedColumnName="id", nullable = false, updatable = true, insertable = true),
            @JoinColumn(name="reference_type", referencedColumnName="reference_type", nullable = false, updatable = true, insertable = true)
            },
            inverseJoinColumns = { @JoinColumn(name = "media_id", referencedColumnName = "id", nullable = false, updatable = false) })
    public Set<MediaEntity> getMedia() {
        return this.media;
    }

    public void setMedia(Set<MediaEntity> media) {
        this.media = media;
    }

    @Basic
    @Column(name = "reference_type", nullable = true, insertable = false, updatable = false)
    public String getReferenceType() {
        return referenceType;
    }

    public void setReferenceType(String referenceType) {
        this.referenceType = referenceType;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (!(obj instanceof PeopleEntity)) return false;
        final PeopleEntity other = (PeopleEntity) obj;
        return Objects.equals(this.id, other.id) &&
                Objects.equals(this.name, other.name);
    }

    @Override
    public String toString() {
        return "PeopleEntity{" +
                ", id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
}

MediaReferenceEntity.java

package com.company.system.hibernate.entities;
    
import javax.persistence.*;
import java.io.Serializable;
import java.util.Objects;

@Entity
@Table(name = "media_reference")
public class MediaReferenceEntity implements Serializable {

    private static final long serialVersionUID = 4550422780535557785L;

    private Integer id;
    private Integer referenceId;
    private String referenceType;
    private MediaEntity media;

    @Id
    @Column(name = "id", nullable = false, length = 10, precision = 0)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "media_id", referencedColumnName = "id")
    public MediaEntity getMedia() {
        return media;
    }

    public void setMedia(MediaEntity media) {
        this.media = media;
    }

    @Basic
    @Column(name = "reference_id", length = 0, precision = 0)
    public Integer getReferenceId() {
        return referenceId;
    }

    public void setReferenceId(Integer referenceId) {
        this.referenceId = referenceId;
    }

    @Basic
    @Column(name = "reference_type", length = 0, precision = 0)
    public String getReferenceType() {
        return referenceType;
    }

    public void setReferenceType(String referenceType) {
        this.referenceType = referenceType;
    }

    @Override
    public String toString() {
        return "MediaReferenceEntity{" +
                ", id='" + id + '\'' +
                ", referenceId='" + referenceId + '\'' +
                ", referenceType='" + referenceType + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        MediaReferenceEntity that = (MediaReferenceEntity) o;

        if (!Objects.equals(id, that.id)) return false;
        if (!Objects.equals(referenceId, that.referenceId)) return false;
        if (!Objects.equals(referenceType, that.referenceType)) return false;
        if (!Objects.equals(media, that.media)) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return Objects.hash(media, referenceId, referenceType);
    }
}

MediaEntity.java

package com.company.system.hibernate.entities;

import javax.persistence.*;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Serializable;

/**
 * <p>MediaEntity class.</p>
 */
@Table(name = "media")
@Entity
public class MediaEntity implements Serializable {

    private static final long serialVersionUID = -1915301587741334140L;

    private Integer id;

    @Column(name = "id", nullable = false, length = 10, precision = 0)
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    private String name;

    @Column(name = "name", nullable = false, length = 100, precision = 0)
    @Basic
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private byte[] file;

    @Column(name = "file", length = 2147483647, precision = 0)
    @Basic(fetch=FetchType.LAZY)
    public byte[] getFile() {
        return file;
    }

    @Transient
    public InputStream getFileStream() {
        return new ByteArrayInputStream(file);
    }

    public void setFile(byte[] file) {
        this.file = file;
    }
}

我觉得复制关系不会有问题table:

TABLE MEDIA (
   MEDIA_ID PK
)

TABLE MEDIA_PEOPLE (
   MEDIA_ID FK
   PEOPLE_ID FK
)

TABLE PEOPLE (
  PEOPLE_ID PK
) 

TABLE MEDIA_CARS (
  MEDIA_ID FK
  CARS_ID FK
)

TABLE CARS (
  CARS_ID PK
)