Skip to content

Instantly share code, notes, and snippets.

@mguilherme
Last active March 5, 2021 09:30
Show Gist options
  • Save mguilherme/1b2ec59298aee11e9ec8233201532734 to your computer and use it in GitHub Desktop.
Save mguilherme/1b2ec59298aee11e9ec8233201532734 to your computer and use it in GitHub Desktop.
Polymorphic example with jsonb
package com.example
import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.annotation.JsonTypeInfo
import com.vladmihalcea.hibernate.type.json.JsonBinaryType
import org.hibernate.annotations.Type
import org.hibernate.annotations.TypeDef
import org.springframework.boot.CommandLineRunner
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.jpa.repository.JpaRepository
import java.io.Serializable
import java.util.*
import javax.persistence.*
@SpringBootApplication
class AuditExampleApplication
fun main(args: Array<String>) {
runApplication<AuditExampleApplication>(*args)
}
@Entity
@Table(name = "orders")
@TypeDef(name = "jsonb", typeClass = JsonBinaryType::class)
data class OrderEntity(
val name: String,
@Enumerated(EnumType.STRING)
var currentStatus: Status,
@Type(type = "jsonb")
@Column(name= "product", columnDefinition = "jsonb")
val product: Product
): Serializable {
@Id
val id: UUID = UUID.randomUUID()
}
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
interface Product: Serializable
data class Book(@JsonProperty("author") val author: String) : Product
data class Pen(@JsonProperty("color") val color: String) : Product
enum class Status {
STARTED, RECEIVED, SENT, DOWNLOADING, COMPLETED
}
interface OrderRepository : JpaRepository<OrderEntity, UUID>
@Configuration
class Config {
@Bean
fun init(orderRepository: OrderRepository) = CommandLineRunner {
val order1 = OrderEntity("my first book", Status.STARTED, Book("my author"))
val order2 = OrderEntity("my second book", Status.RECEIVED, Book("my author"))
val pen1 = OrderEntity("my first pen", Status.COMPLETED, Pen("red"))
val pen2 = OrderEntity("my second pen", Status.DOWNLOADING, Pen("red"))
orderRepository.saveAll(listOf(order1, order2, pen1, pen2))
orderRepository.findAll().forEach { println(it) }
/**
# Prints:
OrderEntity(name=my first book, currentStatus=STARTED, product=Book(author=my author))
OrderEntity(name=my second book, currentStatus=RECEIVED, product=Book(author=my author))
OrderEntity(name=my first pen, currentStatus=COMPLETED, product=Pen(color=red))
OrderEntity(name=my second pen, currentStatus=DOWNLOADING, product=Pen(color=red))
*/
}
}
/**
# Database:
41a0567f-5cd3-4175-91b2-dfc44eac746e COMPLETED my first pen {"color": "red", "@class": "com.example.Pen"}
43592556-c648-4b9a-a53f-3f17e45d6986 RECEIVED my second book {"@class": "com.example.Book", "author": "my author"}
965c050c-7dfa-4c7d-9a27-d5e5d05c99e9 DOWNLOADING my second pen {"color": "red", "@class": "com.example.Pen"}
9bb03be4-740e-4f5e-9115-5d39d2ff1b19 STARTED my first book {"@class": "com.example.Book", "author": "my author"}
*/
// implementation("com.vladmihalcea:hibernate-types-52:2.10.3")
/**
# application.yml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/example
username: postgres
password: postgres
jpa:
hibernate:
ddl-auto: create
logging:
level:
org.hibernate.SQL: DEBUG
# org.hibernate.type.descriptor.sql.BasicBinder: TRACE
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment