Как использовать наследование JPA с QueryDSL? - PullRequest
0 голосов
/ 29 января 2020

У меня есть 1 суперкласс и 3 подкласса.

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "ACTION")
abstract class Action(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val actionId: Long = 0
    /* ... */
)

interface ActionRepo: JpaRepository<Action, Long>, QuerydslPredicateExecutor<Action>

@Entity
@DiscriminatorValue("ACTION_TYPE")
@PrimaryKeyJoinColumn(name = "ACTION_A_ID")
class ActionA(
    val cardId: String
    /* ... */

): Action()


@Entity
@DiscriminatorValue("ACTION_TYPE")
@PrimaryKeyJoinColumn(name = "ACTION_B_ID")
class ActionB(
    val cardId: String
    /* ... */

): Action()


@Entity
@DiscriminatorValue("ACTION_TYPE")
@PrimaryKeyJoinColumn(name = "ACTION_C_ID")
class ActionC(
    // No "cardId" property
    /* ... */

): Action()

И я прошу найти действия по указанному идентификатору карты.

@Service
@Transactional
class ActionService(
    val actionRepo: ActionRepository 
) {

    private fun getConditions(cardId: String): Predicate {
        val action = QAction.action
        val actionA = action.`as`(QActionA::class.java)
        val actionB = action.`as`(QActionB::class.java)
        return actionA.cardId.eq(cardId).or(actionB.cardId.eq(cardId)
    }

    // this
    fun findActions(cardId: String): Collection<Action> {
        val action = QAction.action
        val actions = actionRepo.findAll(getConditions(cardId))

        return actions
    }

}

Но, создано sql как показано ниже.

20200129 22:22:41.297 [http-nio-8880-exec-3] DEBUG j.sqltiming -  com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52)
1. select action0_.ACTION_ID as ACTION_I2_2_, action0_7_.CARD_ID as CARD_ID5_54_, action0_8_.CARD_ID as CARD_ID4_56_ 
  from ACTION action0_
  left outer join ACTION_A action0_6_ on action0_.ACTION_ID=action0_6_.ACTION_A_ID
  left outer join ACTION_B action0_7_ on action0_.ACTION_ID=action0_7_.ACTION_B_ID
  left outer join ACTION_C action0_8_ on action0_.ACTION_ID=action0_8_.ACTION_C_ID
  where action0_6_.CARD_ID='65d3ea22-3410-4b22-97bc-80a10e861d12'
  or action0_6_.CARD_ID='65d3ea22-3410-4b22-97bc-80a10e861d12'

Проблема в том, что я написал ACTION_A .CARD_ID == cardId || ACTION_B .CARD_ID == cardId в условном выражении, но фактический запрос изменился на action0_6 _ ( ACTION_A ). CARD_ID = cardId или action0_6 _ ( ACTION_A ). CARD_ID = cardId .

Я не могу понять, почему ACTION_A вызывался дважды вместо ACTION_B.

...