Skip to content

Instantly share code, notes, and snippets.

@DickyT
Created June 27, 2018 23:21
Show Gist options
  • Save DickyT/b94b0079cea89c987c883aa0ff4aa700 to your computer and use it in GitHub Desktop.
Save DickyT/b94b0079cea89c987c883aa0ff4aa700 to your computer and use it in GitHub Desktop.
package com.kmirai.kis.lib
import com.kmirai.kis.Gson
import org.hibernate.HibernateException
import org.hibernate.dialect.PostgreSQL95Dialect
import org.hibernate.engine.spi.SharedSessionContractImplementor
import org.hibernate.usertype.UserType
import org.springframework.util.ObjectUtils
import java.io.Serializable
import java.sql.PreparedStatement
import java.sql.ResultSet
import java.sql.Types
class PostgreSQLWithGson : PostgreSQL95Dialect() {
init {
this.registerColumnType(Types.JAVA_OBJECT, "jsonb")
}
}
class JsonbAsGsonType : UserType {
override fun hashCode(x: Any?) = x?.hashCode() ?: 0
override fun deepCopy(value: Any?): Any {
if (value != null) {
return Gson.sharedInstance.fromJson(Gson.sharedInstance.toJson(value), value.javaClass)
} else {
throw HibernateException("ERROR: Can not deep copy null")
}
}
override fun replace(original: Any?, target: Any?, owner: Any?) = deepCopy(original)
override fun equals(x: Any?, y: Any?) = ObjectUtils.nullSafeEquals(x, y)
override fun returnedClass(): Class<*> = Any::class.java
override fun assemble(cached: Serializable?, owner: Any?) = deepCopy(cached)
override fun disassemble(value: Any?) = deepCopy(value) as? Serializable ?: ""
override fun nullSafeSet(st: PreparedStatement?, value: Any?, index: Int, session: SharedSessionContractImplementor?) {
if (value == null) {
st!!.setObject(index, "{}", Types.OTHER)
} else {
st!!.setObject(index, Gson.sharedInstance.toJson(value), Types.OTHER)
}
}
override fun nullSafeGet(rs: ResultSet?, names: Array<out String>?, session: SharedSessionContractImplementor?, owner: Any?): Any {
val rawData = rs!!.getString(names!![0])
if (owner != null) {
return Gson.sharedInstance.fromJson(rawData, owner.javaClass.getDeclaredField("data").type)
} else {
throw HibernateException("ERROR: Owner container is null")
}
}
override fun isMutable() = true
override fun sqlTypes() = intArrayOf(Types.JAVA_OBJECT)
}
@DickyT
Copy link
Author

DickyT commented Jun 27, 2018

@TypeDef(name = "JsonbAsGsonType", typeClass = JsonbAsGsonType::class)

@Entity
class Music {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long = 0

    @Column(nullable = false)
    @Type(type = "JsonbAsGsonType")
    lateinit var data: MusicData

    ...
}

@DickyT
Copy link
Author

DickyT commented Jun 27, 2018

This custom JPA type convertor can automatically parse or stringify your jsonb data with Gson. Note that in line 52, you muse use a fixed field name of the jsonb field, or you must figure out how to get the jsonb field in JPA ORM model.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment