Hibernate parameter to tuple

1.3k views Asked by At

I try to implement this sort of SQL query in Hibernate native.

val list = listOf((z,1),(w,2),(y,3))
SELECT * FROM table WHERE (a, b) IN (:list) 

to finally obtain something like:

SELECT * FROM table WHERE (a, b) IN ((z,1),(w,2),(y,3))

I try several implementation with custom UserType or with inspiration of Hibernate-Types from Vlad Mihalcea, but i can't get it.

Is there in Hibernate a way to convert a parameter or a list of parameters to tuple or tuple list?

EDIT

I've succeed to do it, but i'm not 100% glad of it.

To give more context, the couple (a, b) are of types (uuid, timestamp). For this solution work, i need to create a Postgres complex type:

CREATE TYPE pair_uuid_timestamp AS (
  first uuid,
  second timestamp
);

Then, i need a PostgreSQLPairType based on ImmutableType from hibernate-types-52. It's easy to avoid it, but i've already have it.

class PostgreSQLPairType(
  val first: UUID?,
  val second: LocalDateTime?
) : ImmutableType<PostgreSQLPairType>(PostgreSQLPairType::class.java) {

  constructor(): this(null, null)

  override fun sqlTypes(): IntArray {
    return intArrayOf(Types.OTHER)
  }

  @Throws(SQLException::class)
  override fun get(rs: ResultSet, names: Array<String>, session: SharedSessionContractImplementor, owner: Any): PostgreSQLPairType? {
    return null
  }

  @Throws(SQLException::class)
  override fun set(st: PreparedStatement, pair: PostgreSQLPairType?, index: Int, session: SharedSessionContractImplementor) {
    if (pair == null) {
        st.setNull(index, Types.OTHER)
    } else {
        val pgObject = PGobject()
        pgObject.type = "pair_uuid_timestamp"
        pgObject.value = "(${pair.first},${pair.second?.toInstantStr()})"
        st.setObject(index, pgObject)
    }
  }
}

Today, i don't use it for now, i don't see any difference with my parameter list construct like this:

val list = listOf((uuid1,timestamp1),(uuid2,timestamp2),(uuid3,timestamp3))
val parameter = list.joinToString(",") { "('${it.first}', '${it.second.toInstantStr()}')" }
SELECT * FROM table WHERE (a, b) IN (:list) 
0

There are 0 answers