我有以下用例:
现在我希望Parent中的派生字段映射相对于此父项或其子项之一的所有标记。 SQL查询很简单,但我不能通过注释给定的属性来使其工作。 请注意@ManyToOne映射的工作方式类似于魅力,以便找到标记的父所有者,请参阅下面的代码(这是@OneToMany关系,Tag可能不是我能为此示例找到的最佳名称)。
@Entity
@Audited
public class Parent {
@Id
private Long id;
@OneToMany(mappedBy = "parent")
private List<Child> children;
@OneToMany(mappedBy = "parent")
private List<ParentTag> tags;
// Does not work!
@OneToMany(mappedBy = "owner")
private List<Tag<?>> allTags;
}
@Entity
@Audited
public class Child {
@Id
private Long id;
@ManyToOne
private Parent parent;
@OneToMany(mappedBy = "child")
private List<ChildTag> tags;
}
@Entity
@Audited
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Tag<T> {
@Id
private Long id;
protected String value;
@NotAudited // otherwise ClassCastException
@ManyToOne
@JoinColumnsOrFormulas({
@JoinColumnOrFormula(formula = @JoinFormula(
value = "CASE WHEN parent_id IS NOT NULL THEN parent_id WHEN child_id IS NOT NULL THEN (SELECT child.parent_id FROM Child child WHERE child.id = child_id) end",
referencedColumnName="id"))
})
private Parent owner;
public abstract T getNode();
}
@Audited
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class ChildTag extends Tag<Child> {
@ManyToOne
private Child child;
@Override
public Child getNode() {
return child;
}
}
@Audited
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class ParentTag extends Tag<Parent> {
@ManyToOne
private Parent parent;
@Override
public Parent getNode() {
return parent;
}
}
我想找到一种通过给定查询或公式加载allTags的方法。 逆映射@ManyToOne有效(只要未审核所有者,就很难找到该bug)。
我已经尝试了以下解决方案但没有成功:
@JoinColumnsOrFormulas({
@JoinColumnOrFormula(formula = @JoinFormula(
value = "CASE WHEN parent_id IS NOT NULL THEN parent_id WHEN child_id IS NOT NULL THEN (SELECT child.parent_id FROM Child child WHERE child.id = child_id) end",
referencedColumnName="id"))
})
private List<Tag<?>> allTags;
我得到一个ClassCastException,Formula不能转换为列
@Entity
@Audited
@NamedNativeQuery(name = "loadAllTags",
query = "SELECT * FROM Tag tag WHERE "
+ "(tag.parent_id IS NOT NULL AND tag.parent_id = :id) OR "
+ "(tag.child_id IS NOT NULL AND EXISTS (SELECT 1 FROM Child child WHERE child.id = tag.child_id AND child.parent_id = :id))")
public class Parent {
...
@Loader(namedQuery = "loadAllTags")
private List<Tag<?>> allTags;
}
没有例外,实际上在调试时我可以看到加载器找到所有合适的标签,但是没有用它们初始化集合。 我也尝试将查询放在一个hbm配置文件中,因为我知道@Loader和@NamedNativeQuery不能相处得很好,但没有成功(也许我在这里做错了)。但是,我宁愿实施没有配置文件的解决方案。
我可以添加另一列(owner_id),但如果我能找到解决问题的方法而不更改模型,那就更好了。
我不知道仿制药是否与它有关。此外,我的实体也经过审计和索引。
任何帮助将不胜感激!