@OneToMany с @JoinFormula с использованием полиморфизма и общего

У меня есть следующий вариант использования:

  • Родители содержат Дети и Родительские Теги.
  • Дети содержат ChildrenTags и их родительский узел.
  • Теги ParentTag и ChildrenTag являются тегами, где T является родительским или дочерним тегами.

Теперь я хочу получить производное поле в Parent, которое отображает все теги относительно этого родителя или одного из его дочерних элементов. SQL-запрос прост, но я не могу заставить его работать, аннотируя данное свойство. Обратите внимание, что отображение @ManyToOne работает как шарм, чтобы найти владельца Parent для тега, см. Мой код ниже (это отношение @OneToMany, тег, возможно, не лучшее имя, которое я мог найти для этого примера).

Parent.class

@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;

}

Child.class

@Entity
@Audited
public class Child {

    @Id
    private Long id;

    @ManyToOne
    private Parent parent;

    @OneToMany(mappedBy = "child")
    private List<ChildTag> tags;

}

Tag.class

@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();

}

ChildTag.class

@Audited
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class ChildTag extends Tag<Child> {

    @ManyToOne
    private Child child;

    @Override
    public Child getNode() {
        return child;
    }

}

ParentTag.class

@Audited
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class ParentTag extends Tag<Parent> {

    @ManyToOne
    private Parent parent;

    @Override
    public Parent getNode() {
        return parent;
    }

}

Я хотел бы найти способ загрузить все теги по заданному запросу или формуле. Обратное отображение @ManyToOne работает (пока владелец не проверен, эту ошибку было трудно найти).

Я уже попробовал следующие решения без успеха:

@JoinFormula

    @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, формула не может быть приведена в столбец

@Loader

@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), но если бы я мог найти способ решить эту проблему без изменения модели, было бы лучше.

Я не знаю, имеют ли дженерики какое-то отношение к этому. Кроме того, мои объекты проверяются и индексируются.

Любая помощь будет оценена!

0 ответов

Другие вопросы по тегам