Hibernate,间接关系映射

Hibernate, indirect relations mapping

我有两个表:Word 和 Stems。第二个字段是 Word 的外键。这么多词干可以属于一个词。

在 Java 中,我创建了 Entities Word 和 Stem。因为 word 可以有很多词干,而且我对这个词干的列表有一些操作,所以我决定将这个列表和相应的方法放在单独的 class 中,称为 Stems。此 class 的对象在 Word 实体中。下面我展示了我的代码的样子:


Word.java

@Entity
@Table(name = "Word")
@Inheritance(strategy=InheritanceType.JOINED)  
public abstract class Word implements Serializable{

    // primary key and other columns

    @Transient
    protected Stems stems = new Stems();

    public void setStems(List<Stem> stems) {
        this.stems.setStems(stems);
    }

    @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER, mappedBy="word")
    public List<Stem> getStems() {
        return stems.getStems();
    }
}

Stems.java

public class Stems {

    private List<Stem> stems = new ArrayList<>();

    public List<Stem> getStems() {
        return stems;
    }

    public void setStems(List<Stem> stems) {
        this.stems = stems;
    }
}

Stem.java

@Entity  
@Table(name = "Stems")  
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)  
@DiscriminatorColumn(name="Type",discriminatorType=DiscriminatorType.STRING)  
public abstract class Stem implements Cloneable{

    @Id
    @Column(name = "Stem", unique = true, nullable = false, length = 64)
    private String rawStem;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "WordId", nullable = false)
    private Word word;
}

我的问题来了。是否可以进行 HQL 查询以获取具有正确词干的单词?如果没有那么如何实现这一点。也许这种结构不允许工作?我怎样才能 add/update 带词干的单词?我尝试在每个词干中设置词干数组和词 ID,然后使用 session.merge(word) 但它不起作用。

我看到了光。我想在这里粘贴我的问题的完整解决方案。此解决方案仅允许通过调用包含词干列表的词对象 session.merge 来修改词干 table。

请注意注解@Embedded@EmbeddableorphanRemoval中的参数 =]@OneToMany注解。


Word.java

@Entity
@Table(name = "Word")
@Inheritance(strategy=InheritanceType.JOINED)  
public abstract class Word implements Serializable{

    // primary key and other columns

    @Embedded
    protected Stems stems = new Stems();

    public List<Stem> getStems() {
        return stems.getStems();
    }

    public void setStems(List<Stem> stems) {
        this.stems.setStems(stems);
    }
}

Stems.java

@Embeddable
public class Stems {
    // orphanRemoval removes stems which is present in database but not on list
    @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER, mappedBy="word", orphanRemoval = true)
    private List<Stem> stems = new ArrayList<>();

    // getters/setters
}

Stem.java - 没有变化。