Hibernate @ Где не работает с @NamedEntityGraph

Я пытаюсь использовать @Where аннотация спящего режима на однонаправленном @ManyToMany ассоциация при использовании @NamedEntityGraph на родительском объекте (см. код ниже):

ПРИМЕЧАНИЕ. Я переименовал свои объекты в Parent а также Childнапример саке. Кроме того, я использую Kotlin, который не должен иметь никакого значения, кроме синтаксиса.

Класс сущности

@Entity
@Table(name = "Parent")
@NamedEntityGraph(
        name = "parent",
        attributeNodes = [
            NamedAttributeNode(value = "children")
        ]
)
class Parent(

        @Id
        @Column(name = "parent_id")
        var id: Long,

        @Column(name = "some_value")
        var someValue: Long,

        @ManyToMany(targetEntity = Child::class, fetch = FetchType.LAZY)
        @Where(clause = "state <> 'deleted'")
        @JoinTable(name = "Parent_Child",
                joinColumns = [JoinColumn(name = "parent_id")],
                inverseJoinColumns = [JoinColumn(name = "child_id")])
        var children: Set<Child>?

)

Репозиторий JPA

interface ParentRepository : JpaRepository<Parent, Long> {

    @EntityGraph(value = "parent")
    fun findBySomeValue(someValue: Long): List<Parent>

//    Tried this commented-out code, but that just added another condition to the 
//    final `WHERE` clause and not the `JOIN` condition.
//    @EntityGraph(value = "parent")
//    fun findBySomeValueAndChildrenStateNot(SomeValue: Long, state: String): List<Parent>
}

Оператор SQL, созданный Hibernate в консоли

Hibernate:
    select
        parent0_.parent_id as parent_1_1_0_,
        child2_.child_id as child_1_1_0_,
        parent0_.parent_id as some_v2_1_0_,
        child2_.state as state_2_1_0_ 
    from
        Parent parent0_ 
    left outer join
        Parent_Child children1_ 
            on parent0_.parent_id=children1_.parent_id 
    left outer join
        Child child2_ 
            on children1_.child_id=child2_.child_id 
            and (
                child2_.state <> 'deleted'
            ) 
    where
        parent0_.some_value=?
Hibernate: 
    select
        child0_.child_id as child_id1_15_0_,
        child0_.state as state_2_15_0_
    from
        Child child0_ 
    where
        child0_.child_id=?
Hibernate: 
    select
        child0_.child_id as child_id1_15_0_,
        child0_.state as state_2_15_0_
    from
        Child child0_ 
    where
        child0_.child_id=?

Результат JSON

[
  {
    "id": 1,
    "someValue": 1234,
    "children": [
      {
        "childId": 1,
        "state": "deleted"
      },
      {
        "childId": 2,
        "state": "active"
      }
    ]
  }
]

вопросы

Есть пара проблем:

1) Как вы можете видеть для операторов SQL, Hibernate может использовать один запрос с объединениями для получения данных, но он также инициализирует больше операторов выбора SQL для каждой из дочерних связанных сущностей. Hibernate должен использовать только первый выбор с объединениями.

2) Хотя первый SQL SELECT заявление имеет state <> 'deleted' пункт в JOIN заявление, JSON результат имеет детей с обоими active а также deleted state. Это связано с двумя дополнительными операторами выбора.

Резюме / Мысли

Сначала я думал, что это из-за fetchType=LAZY и это когда ParentGSON выполнял сериализацию объекта, он вызывал функцию "getter" и заставлял Hibernate извлекать данные, однако это не так. Я также пробовал изменить его наfetchType=EAGER, но это ничего не изменило.

Это похоже на ошибку Hibernate, но я недостаточно знаком с этим вариантом использования, чтобы действительно сказать, является ли это ошибкой или я просто реализую что-то не так.

По сути, как сообщить Hibernate, чтобы он не запускал лишние операторы SELECT, а просто использовал первый с JOIN?

0 ответов

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