SlideShare uma empresa Scribd logo
1 de 35
Baixar para ler offline
Alternatives of JPA
CatalogTribe in Shanghai
debop@coupang.com 2018.01.16
Agenda
• What is ORM
• Pros / Cons of JPA
• Current status in Coupang
• Alternatives of JPA
• Slick
• jOOQ
• Exposed
• Requery
ORM (Object Relational Mapping)
• OOP’s object graph vs Relational Database
• Focus OOP, not Relational Database
• No matter of RDBMS vendor - Same code
• Hibernate coverage is 95% over traditional SQL statements
• ORM not suitable for data centric application in performance
• Why should you use an ORM?
Pros of JPA
• Focus to Java Object graph & OOP
• No need to know relations and constraints of entities
• No need to know specific DB features by various vendor
• No need to know SQL, just use Java API
• Supplement by HQL or JPQL or QueryDSL
• All support for Stateful, Stateless (Default is Stateful)
Cons of JPA
• If you knew SQL already, JPA is wired
• Hard to learning (exponential)
• Low performance by stateful and fetch by id
• No suitable for Bulk or Set operations
• Massive Insert, Statistical Summary (Cube …)
• Non-Threadsafe Session - Low throughput
• Need to learn specific JPAVendor (Hibernate, Eclipse Link)
• HQL, @DynamicInsert, @LazyCollection
• 2nd Cache (recommend JCache (JSR-305))
Current Status in Coupang
• No Deep Dive
• Missing override (hashCode, equals, toString)
• No using @NatualId
• Bad Policy / Bad Design
• Every entity has Own identifier (Some case no need)
• Poor performance -> Mislead “JPA is bad”
• Apply not suitable case
• Bulk operations, Statistical operations
• No use supplement features
• StatelessSession, 2nd Cache …
Features in Alternatives of JPA
• Design Principle
• OOP based, Support Multi DBVendor
• No need stateful for Reference object
• Support association, inheritance, converter in JPA
• Performance
• Speed up like Plain SQL
• Stateless
• Support Asynchronous or Reactive
• Support Bulk or Batch operations
Slick
ORM for Scala
Slick
• Database access library
• Not ORM -> Functional Relational Mapping
• Bring relational model to Scala OOP
• Natural fit ( no impedance mismatch)
• Stateless
• Matures (Slick version 3) (Non-blocking DBIO)
• Essential Slick Book
Slick - schema definition
Entity
Schema
Definition
Slick - Query
// Get Users with age > 20
Query statement
Async
Operations
Slick - DML
Slick -Transactions
Define Repository
Async
Execution with
Transaction
Slick - Plain SQL
ResultSet to
Tuple
ResultSet to
Entity
jOOQ
Java Object Oriented Query
jOOQ
• Reflect Database Schema to generate Entity Class
• Typesfe SQL (akaTypesafe MyBatis)
• Database First (Not ORM)
• Stateless
• Need DBMS Owner Authority
• jOOQ vs Hibernate :When to choose which
jOOQ - Generate Codes
jOOQ - typesafe SQL
SELECT * FROM BOOK
WHERE BOOK.PUBLISHED_IN = 2011
ORDER BY BOOK.TITLE
create.selectFrom(BOOK)
.where(BOOK.PUBLISHED_IN.eq(2011))
.orderBy(BOOK.TITLE)
select().from(t).where(t.a.eq(select(t2.x).from(t2));
// Type-check here: ---------------> ^^^^
select().from(t).where(t.a.eq(any(select(t2.x).from(t2)));
// Type-check here: -------------------> ^^^^
select().from(t).where(t.a.in(select(t2.x).from(t2));
// Type-check here: ---------------> ^^^^
select(t1.a).from(t1).unionAll(select(t2.a).from(t2));
// Type-check here: ----------------> ^^^^
select(t1.a, t1.b).from(t1).union(select(t2.a, t2.b).from(t2));
// Type-check here: -------------------> ^^^^^^^^^^
Predicates
Set operations
requery
ORM for Java & Kotlin & Android
requery
• No reflection (apt code generation) - Fast instancing
• Fast startup & performance
• Schema generation
• Blocking / Non-blocking API (Reactive with RxJava)
• Support partial object / refresh / upsert
• Custom type converter like JPA
• Compile time entity validation
• Support almost JPA annotations
@Entity
abstract class AbstractPerson { 
    @Key @Generated int id; 
   
    @Index("name_index") // table specification 
    String name;     
   
    @OneToMany // relationships 1:1, 1:many, many to many   
    Set<Phone> phoneNumbers;
   
    @Converter(EmailToStringConverter.class)
    Email email;
    @PostLoad // lifecycle callbacks
    void afterLoad() { updatePeopleList(); }
    // getter, setters, equals & hashCode automatically generated into Person.java 
}
requery - define entity
Identifier
Entity class
Converter
Listeners
Result<Person> query = data
    .select(Person.class)
    .where(Person.NAME.lower().like("b%"))
    .and(Person.AGE.gt(20))
    .orderBy(Person.AGE.desc())
    .limit(5)
    .get();
Observable<Person> observable = data
    .select(Person.class)
    .orderBy(Person.AGE.desc())
    .get()
    .observable();
requery - query
Query by Fluent API
Reactive Programming
Cold Observable
Non blocking
@Entity(model = "tree")

interface TreeNode {

    @get:Key

    @get:Generated

    val id: Long
   
    @get:Column

    var name: String



    @get:ManyToOne(cascade = [DELETE])
    var parent: TreeNode?



    @get:OneToMany(mappedBy = "parent", cascade = [SAVE, DELETE])

    val children: MutableSet<TreeNode>
}
requery - self refence by Kotlin
Identifier
Entity class
1:N, N:1
Cascade
requery - Blob/Clob usage
class ByteArrayBlobConverter : Converter<ByteArray, Blob> {
override fun getPersistedSize(): Int? = null
override fun getPersistedType(): Class<Blob> = Blob::class.java
override fun getMappedType(): Class<ByteArray> = ByteArray::class.java
override fun convertToMapped(type: Class<out ByteArray>?, value: Blob?): ByteArray? {
return value?.binaryStream?.readBytes()
}
override fun convertToPersisted(value: ByteArray?): Blob? {
return value?.let { SerialBlob(it) }
}
}
requery - Blob property
@Entity(model = "kt")
interface BigModel {
@get:Key
@get:Generated
@get:Column(name = "model_id")
val id: Int
@get:Column(name = "model_name")
var name: String?
@get:Convert(value = ByteArrayBlobConverter::class)
@get:Column(name = "model_picture")
var picture: ByteArray?
}
Blob column
Exposed
Kotlin SQL Framework
Exposed - Kotlin SQL Framework
• Lightweight SQL Library
• Provide two layers of data access
• Typesafe SQL wrapping DSL
• Lightweight Data Access Object
• See : First steps with Kotlin/Exposed
• Cons
• Not support parameterized SQL
Exposed - SQL DSL
object Users : Table() {
    val id = varchar("id", 10).primaryKey() // Column<String> 
    val name = varchar("name", length = 50) // Column<String>
    val cityId = (integer("city_id") references Cities.id).nullable() // Column<Int?>
}
object Cities : Table() { 
    val id = integer("id").autoIncrement().primaryKey() // Column<Int>
    val name = varchar("name", 50) // Column<String> 
}
Exposed - SQL DSL
val munichId = Cities.insert {
    it[name] = "Munich"
} get Cities.id 
Cities.insert { it[name] = "Prague" } 
Users.insert { 
    it[id] = "andrey" 
    it[name] = "Andrey" 
    it[cityId] = saintPetersburgId 
}
Users.insert { 
    it[id] = "sergey"
    it[name] = "Sergey" 
    it[cityId] = munichId
}
Exposed - SQL DSL - Join
(Users innerJoin Cities)
    .slice(Users.name, Cities.name)
    .select {
        (Users.id.eq("andrey") or Users.name.eq("Sergey")) and
        Users.id.eq("sergey") and Users.cityId.eq(Cities.id)
    }
    .forEach { 
        println("${it[Users.name]} lives in ${it[Cities.name]}")
    }
Exposed - SQL DSL - Join 2
((Cities innerJoin Users)
    .slice(Cities.name, Users.id.count())
    .selectAll()
    .groupBy(Cities.name))
    .forEach {
        val cityName = it[Cities.name]
        val userCount = it[Users.id.count()]
        if (userCount > 0) {
            println("$userCount user(s) live(s) in $cityName")
        } else { 
            println("Nobody lives in $cityName")
        }
     }
Exposed - DAO
object Users : IntIdTable() {
    val name = varchar("name", 50).index()
    val city = reference("city", Cities)
    val age = integer("age")
}
object Cities: IntIdTable() { 
    val name = varchar("name", 50)
}
Schema Definition
class User(id: EntityID<Int>) : IntEntity(id){
    companion object : IntEntityClass<User>(Users)
    var name by Users.name
    var city by City referencedOn Users.city
    var age by Users.age 
}
class City(id: EntityID<Int>) : IntEntity(id) {
    companion object : IntEntityClass<City>(Cities)
    var name by Cities.name
    val users by User referrersOn Users.city 
}
Entity Definition
Exposed - DAO Usage
val munich = City.new {
    name = "Munich"
}
User.new {
    name = "a"
    city = munich
    age = 5
}
User.new {
    name = "b"
    city = munich
    age = 27
}
munich.users.joinToString { it.name }
User.find { Users.age.between(18, 60) }
OneTo Many
All user’s name in Munich
Conclusion
• Already legacy database exists ? Use only Java
• jOOQ or requery
• Scala only ? -> Slick
• Kotlin only ? -> requery, Exposed
• No matter language? -> requery
• Need Reactive programming? ->
• requery with kotlinx-requery
• kotlinx-rxjava2-jdbc ( we will open March )
Thank you!

Mais conteúdo relacionado

Mais procurados

BASTA 2013: Custom OData Provider
BASTA 2013: Custom OData ProviderBASTA 2013: Custom OData Provider
BASTA 2013: Custom OData ProviderRainer Stropek
 
Scala at HUJI PL Seminar 2008
Scala at HUJI PL Seminar 2008Scala at HUJI PL Seminar 2008
Scala at HUJI PL Seminar 2008Yardena Meymann
 
Demystifying Oak Search
Demystifying Oak SearchDemystifying Oak Search
Demystifying Oak SearchJustin Edelson
 
Kotlin is charming; The reasons Java engineers should start Kotlin.
Kotlin is charming; The reasons Java engineers should start Kotlin.Kotlin is charming; The reasons Java engineers should start Kotlin.
Kotlin is charming; The reasons Java engineers should start Kotlin.JustSystems Corporation
 
Clojure Intro
Clojure IntroClojure Intro
Clojure Introthnetos
 
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald Pehl"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald PehlGWTcon
 
Kotlin: Why Do You Care?
Kotlin: Why Do You Care?Kotlin: Why Do You Care?
Kotlin: Why Do You Care?intelliyole
 
Akka Actor presentation
Akka Actor presentationAkka Actor presentation
Akka Actor presentationGene Chang
 
#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기Arawn Park
 
Advance Java Programs skeleton
Advance Java Programs skeletonAdvance Java Programs skeleton
Advance Java Programs skeletonIram Ramrajkar
 
Kotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsKotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsBartosz Kosarzycki
 
Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一
Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一
Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一scalaconfjp
 
Scala ActiveRecord
Scala ActiveRecordScala ActiveRecord
Scala ActiveRecordscalaconfjp
 

Mais procurados (20)

Scala coated JVM
Scala coated JVMScala coated JVM
Scala coated JVM
 
BASTA 2013: Custom OData Provider
BASTA 2013: Custom OData ProviderBASTA 2013: Custom OData Provider
BASTA 2013: Custom OData Provider
 
Scala at HUJI PL Seminar 2008
Scala at HUJI PL Seminar 2008Scala at HUJI PL Seminar 2008
Scala at HUJI PL Seminar 2008
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Kotlin talk
Kotlin talkKotlin talk
Kotlin talk
 
Scale up your thinking
Scale up your thinkingScale up your thinking
Scale up your thinking
 
Demystifying Oak Search
Demystifying Oak SearchDemystifying Oak Search
Demystifying Oak Search
 
Kotlin is charming; The reasons Java engineers should start Kotlin.
Kotlin is charming; The reasons Java engineers should start Kotlin.Kotlin is charming; The reasons Java engineers should start Kotlin.
Kotlin is charming; The reasons Java engineers should start Kotlin.
 
Slickdemo
SlickdemoSlickdemo
Slickdemo
 
All about scala
All about scalaAll about scala
All about scala
 
Clojure Intro
Clojure IntroClojure Intro
Clojure Intro
 
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald Pehl"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
 
Kotlin: Why Do You Care?
Kotlin: Why Do You Care?Kotlin: Why Do You Care?
Kotlin: Why Do You Care?
 
Akka Actor presentation
Akka Actor presentationAkka Actor presentation
Akka Actor presentation
 
#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기
 
Advance Java Programs skeleton
Advance Java Programs skeletonAdvance Java Programs skeleton
Advance Java Programs skeleton
 
Scala active record
Scala active recordScala active record
Scala active record
 
Kotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsKotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projects
 
Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一
Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一
Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一
 
Scala ActiveRecord
Scala ActiveRecordScala ActiveRecord
Scala ActiveRecord
 

Semelhante a Alternatives of JPA/Hibernate

Spring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffSpring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffJAX London
 
ActiveJDBC - ActiveRecord implementation in Java
ActiveJDBC - ActiveRecord implementation in JavaActiveJDBC - ActiveRecord implementation in Java
ActiveJDBC - ActiveRecord implementation in Javaipolevoy
 
Using the latest Java Persistence API 2 Features - Tech Days 2010 India
Using the latest Java Persistence API 2 Features - Tech Days 2010 IndiaUsing the latest Java Persistence API 2 Features - Tech Days 2010 India
Using the latest Java Persistence API 2 Features - Tech Days 2010 IndiaArun Gupta
 
JSLT: JSON querying and transformation
JSLT: JSON querying and transformationJSLT: JSON querying and transformation
JSLT: JSON querying and transformationLars Marius Garshol
 
Database Programming Techniques
Database Programming TechniquesDatabase Programming Techniques
Database Programming TechniquesRaji Ghawi
 
Jdbc presentation
Jdbc presentationJdbc presentation
Jdbc presentationnrjoshiee
 
Using the latest Java Persistence API 2.0 features
Using the latest Java Persistence API 2.0 featuresUsing the latest Java Persistence API 2.0 features
Using the latest Java Persistence API 2.0 featuresArun Gupta
 
Understanding
Understanding Understanding
Understanding Arun Gupta
 
What's new in Java 8
What's new in Java 8What's new in Java 8
What's new in Java 8Kyle Smith
 
Painless Persistence in a Disconnected World
Painless Persistence in a Disconnected WorldPainless Persistence in a Disconnected World
Painless Persistence in a Disconnected WorldChristian Melchior
 
Easy data-with-spring-data-jpa
Easy data-with-spring-data-jpaEasy data-with-spring-data-jpa
Easy data-with-spring-data-jpaStaples
 
fuser interface-development-using-jquery
fuser interface-development-using-jqueryfuser interface-development-using-jquery
fuser interface-development-using-jqueryKostas Mavridis
 
Postgres vs Mongo / Олег Бартунов (Postgres Professional)
Postgres vs Mongo / Олег Бартунов (Postgres Professional)Postgres vs Mongo / Олег Бартунов (Postgres Professional)
Postgres vs Mongo / Олег Бартунов (Postgres Professional)Ontico
 
CBStreams - Java Streams for ColdFusion (CFML)
CBStreams - Java Streams for ColdFusion (CFML)CBStreams - Java Streams for ColdFusion (CFML)
CBStreams - Java Streams for ColdFusion (CFML)Ortus Solutions, Corp
 
ITB2019 CBStreams : Accelerate your Functional Programming with the power of ...
ITB2019 CBStreams : Accelerate your Functional Programming with the power of ...ITB2019 CBStreams : Accelerate your Functional Programming with the power of ...
ITB2019 CBStreams : Accelerate your Functional Programming with the power of ...Ortus Solutions, Corp
 

Semelhante a Alternatives of JPA/Hibernate (20)

Naver_alternative_to_jpa
Naver_alternative_to_jpaNaver_alternative_to_jpa
Naver_alternative_to_jpa
 
Spring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffSpring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard Wolff
 
Scala and Spring
Scala and SpringScala and Spring
Scala and Spring
 
ActiveJDBC - ActiveRecord implementation in Java
ActiveJDBC - ActiveRecord implementation in JavaActiveJDBC - ActiveRecord implementation in Java
ActiveJDBC - ActiveRecord implementation in Java
 
Using the latest Java Persistence API 2 Features - Tech Days 2010 India
Using the latest Java Persistence API 2 Features - Tech Days 2010 IndiaUsing the latest Java Persistence API 2 Features - Tech Days 2010 India
Using the latest Java Persistence API 2 Features - Tech Days 2010 India
 
JSLT: JSON querying and transformation
JSLT: JSON querying and transformationJSLT: JSON querying and transformation
JSLT: JSON querying and transformation
 
S313431 JPA 2.0 Overview
S313431 JPA 2.0 OverviewS313431 JPA 2.0 Overview
S313431 JPA 2.0 Overview
 
Database Programming Techniques
Database Programming TechniquesDatabase Programming Techniques
Database Programming Techniques
 
Jdbc presentation
Jdbc presentationJdbc presentation
Jdbc presentation
 
Using the latest Java Persistence API 2.0 features
Using the latest Java Persistence API 2.0 featuresUsing the latest Java Persistence API 2.0 features
Using the latest Java Persistence API 2.0 features
 
Understanding
Understanding Understanding
Understanding
 
What's new in Java 8
What's new in Java 8What's new in Java 8
What's new in Java 8
 
Linq
LinqLinq
Linq
 
Painless Persistence in a Disconnected World
Painless Persistence in a Disconnected WorldPainless Persistence in a Disconnected World
Painless Persistence in a Disconnected World
 
Easy data-with-spring-data-jpa
Easy data-with-spring-data-jpaEasy data-with-spring-data-jpa
Easy data-with-spring-data-jpa
 
fuser interface-development-using-jquery
fuser interface-development-using-jqueryfuser interface-development-using-jquery
fuser interface-development-using-jquery
 
Jpa
JpaJpa
Jpa
 
Postgres vs Mongo / Олег Бартунов (Postgres Professional)
Postgres vs Mongo / Олег Бартунов (Postgres Professional)Postgres vs Mongo / Олег Бартунов (Postgres Professional)
Postgres vs Mongo / Олег Бартунов (Postgres Professional)
 
CBStreams - Java Streams for ColdFusion (CFML)
CBStreams - Java Streams for ColdFusion (CFML)CBStreams - Java Streams for ColdFusion (CFML)
CBStreams - Java Streams for ColdFusion (CFML)
 
ITB2019 CBStreams : Accelerate your Functional Programming with the power of ...
ITB2019 CBStreams : Accelerate your Functional Programming with the power of ...ITB2019 CBStreams : Accelerate your Functional Programming with the power of ...
ITB2019 CBStreams : Accelerate your Functional Programming with the power of ...
 

Mais de Sunghyouk Bae

Introduction of failsafe
Introduction of failsafeIntroduction of failsafe
Introduction of failsafeSunghyouk Bae
 
Java naming strategy (자바 명명 전략)
Java naming strategy (자바 명명 전략)Java naming strategy (자바 명명 전략)
Java naming strategy (자바 명명 전략)Sunghyouk Bae
 
테스트자동화와 TDD
테스트자동화와 TDD테스트자동화와 TDD
테스트자동화와 TDDSunghyouk Bae
 
SpringBoot with MyBatis, Flyway, QueryDSL
SpringBoot with MyBatis, Flyway, QueryDSLSpringBoot with MyBatis, Flyway, QueryDSL
SpringBoot with MyBatis, Flyway, QueryDSLSunghyouk Bae
 
좋은 개발자 되기
좋은 개발자 되기좋은 개발자 되기
좋은 개발자 되기Sunghyouk Bae
 
Multithread pattern 소개
Multithread pattern 소개Multithread pattern 소개
Multithread pattern 소개Sunghyouk Bae
 

Mais de Sunghyouk Bae (10)

Introduction of failsafe
Introduction of failsafeIntroduction of failsafe
Introduction of failsafe
 
measure metrics
measure metricsmeasure metrics
measure metrics
 
Java naming strategy (자바 명명 전략)
Java naming strategy (자바 명명 전략)Java naming strategy (자바 명명 전략)
Java naming strategy (자바 명명 전략)
 
테스트자동화와 TDD
테스트자동화와 TDD테스트자동화와 TDD
테스트자동화와 TDD
 
SpringBoot with MyBatis, Flyway, QueryDSL
SpringBoot with MyBatis, Flyway, QueryDSLSpringBoot with MyBatis, Flyway, QueryDSL
SpringBoot with MyBatis, Flyway, QueryDSL
 
JUnit & AssertJ
JUnit & AssertJJUnit & AssertJ
JUnit & AssertJ
 
좋은 개발자 되기
좋은 개발자 되기좋은 개발자 되기
좋은 개발자 되기
 
Using AdoRepository
Using AdoRepositoryUsing AdoRepository
Using AdoRepository
 
Multithread pattern 소개
Multithread pattern 소개Multithread pattern 소개
Multithread pattern 소개
 
Strategy Maps
Strategy MapsStrategy Maps
Strategy Maps
 

Último

Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...Akihiro Suda
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 

Último (20)

Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 

Alternatives of JPA/Hibernate

  • 1. Alternatives of JPA CatalogTribe in Shanghai debop@coupang.com 2018.01.16
  • 2. Agenda • What is ORM • Pros / Cons of JPA • Current status in Coupang • Alternatives of JPA • Slick • jOOQ • Exposed • Requery
  • 3. ORM (Object Relational Mapping) • OOP’s object graph vs Relational Database • Focus OOP, not Relational Database • No matter of RDBMS vendor - Same code • Hibernate coverage is 95% over traditional SQL statements • ORM not suitable for data centric application in performance • Why should you use an ORM?
  • 4. Pros of JPA • Focus to Java Object graph & OOP • No need to know relations and constraints of entities • No need to know specific DB features by various vendor • No need to know SQL, just use Java API • Supplement by HQL or JPQL or QueryDSL • All support for Stateful, Stateless (Default is Stateful)
  • 5. Cons of JPA • If you knew SQL already, JPA is wired • Hard to learning (exponential) • Low performance by stateful and fetch by id • No suitable for Bulk or Set operations • Massive Insert, Statistical Summary (Cube …) • Non-Threadsafe Session - Low throughput • Need to learn specific JPAVendor (Hibernate, Eclipse Link) • HQL, @DynamicInsert, @LazyCollection • 2nd Cache (recommend JCache (JSR-305))
  • 6. Current Status in Coupang • No Deep Dive • Missing override (hashCode, equals, toString) • No using @NatualId • Bad Policy / Bad Design • Every entity has Own identifier (Some case no need) • Poor performance -> Mislead “JPA is bad” • Apply not suitable case • Bulk operations, Statistical operations • No use supplement features • StatelessSession, 2nd Cache …
  • 7. Features in Alternatives of JPA • Design Principle • OOP based, Support Multi DBVendor • No need stateful for Reference object • Support association, inheritance, converter in JPA • Performance • Speed up like Plain SQL • Stateless • Support Asynchronous or Reactive • Support Bulk or Batch operations
  • 9. Slick • Database access library • Not ORM -> Functional Relational Mapping • Bring relational model to Scala OOP • Natural fit ( no impedance mismatch) • Stateless • Matures (Slick version 3) (Non-blocking DBIO) • Essential Slick Book
  • 10. Slick - schema definition Entity Schema Definition
  • 11. Slick - Query // Get Users with age > 20 Query statement Async Operations
  • 14. Slick - Plain SQL ResultSet to Tuple ResultSet to Entity
  • 16. jOOQ • Reflect Database Schema to generate Entity Class • Typesfe SQL (akaTypesafe MyBatis) • Database First (Not ORM) • Stateless • Need DBMS Owner Authority • jOOQ vs Hibernate :When to choose which
  • 18. jOOQ - typesafe SQL SELECT * FROM BOOK WHERE BOOK.PUBLISHED_IN = 2011 ORDER BY BOOK.TITLE create.selectFrom(BOOK) .where(BOOK.PUBLISHED_IN.eq(2011)) .orderBy(BOOK.TITLE) select().from(t).where(t.a.eq(select(t2.x).from(t2)); // Type-check here: ---------------> ^^^^ select().from(t).where(t.a.eq(any(select(t2.x).from(t2))); // Type-check here: -------------------> ^^^^ select().from(t).where(t.a.in(select(t2.x).from(t2)); // Type-check here: ---------------> ^^^^ select(t1.a).from(t1).unionAll(select(t2.a).from(t2)); // Type-check here: ----------------> ^^^^ select(t1.a, t1.b).from(t1).union(select(t2.a, t2.b).from(t2)); // Type-check here: -------------------> ^^^^^^^^^^ Predicates Set operations
  • 19. requery ORM for Java & Kotlin & Android
  • 20. requery • No reflection (apt code generation) - Fast instancing • Fast startup & performance • Schema generation • Blocking / Non-blocking API (Reactive with RxJava) • Support partial object / refresh / upsert • Custom type converter like JPA • Compile time entity validation • Support almost JPA annotations
  • 21. @Entity abstract class AbstractPerson {      @Key @Generated int id;          @Index("name_index") // table specification      String name;              @OneToMany // relationships 1:1, 1:many, many to many        Set<Phone> phoneNumbers;         @Converter(EmailToStringConverter.class)     Email email;     @PostLoad // lifecycle callbacks     void afterLoad() { updatePeopleList(); }     // getter, setters, equals & hashCode automatically generated into Person.java  } requery - define entity Identifier Entity class Converter Listeners
  • 22. Result<Person> query = data     .select(Person.class)     .where(Person.NAME.lower().like("b%"))     .and(Person.AGE.gt(20))     .orderBy(Person.AGE.desc())     .limit(5)     .get(); Observable<Person> observable = data     .select(Person.class)     .orderBy(Person.AGE.desc())     .get()     .observable(); requery - query Query by Fluent API Reactive Programming Cold Observable Non blocking
  • 23. @Entity(model = "tree")
 interface TreeNode {
     @get:Key
     @get:Generated
     val id: Long         @get:Column
     var name: String
 
     @get:ManyToOne(cascade = [DELETE])     var parent: TreeNode?
 
     @get:OneToMany(mappedBy = "parent", cascade = [SAVE, DELETE])
     val children: MutableSet<TreeNode> } requery - self refence by Kotlin Identifier Entity class 1:N, N:1 Cascade
  • 24. requery - Blob/Clob usage class ByteArrayBlobConverter : Converter<ByteArray, Blob> { override fun getPersistedSize(): Int? = null override fun getPersistedType(): Class<Blob> = Blob::class.java override fun getMappedType(): Class<ByteArray> = ByteArray::class.java override fun convertToMapped(type: Class<out ByteArray>?, value: Blob?): ByteArray? { return value?.binaryStream?.readBytes() } override fun convertToPersisted(value: ByteArray?): Blob? { return value?.let { SerialBlob(it) } } }
  • 25. requery - Blob property @Entity(model = "kt") interface BigModel { @get:Key @get:Generated @get:Column(name = "model_id") val id: Int @get:Column(name = "model_name") var name: String? @get:Convert(value = ByteArrayBlobConverter::class) @get:Column(name = "model_picture") var picture: ByteArray? } Blob column
  • 27. Exposed - Kotlin SQL Framework • Lightweight SQL Library • Provide two layers of data access • Typesafe SQL wrapping DSL • Lightweight Data Access Object • See : First steps with Kotlin/Exposed • Cons • Not support parameterized SQL
  • 28. Exposed - SQL DSL object Users : Table() {     val id = varchar("id", 10).primaryKey() // Column<String>      val name = varchar("name", length = 50) // Column<String>     val cityId = (integer("city_id") references Cities.id).nullable() // Column<Int?> } object Cities : Table() {      val id = integer("id").autoIncrement().primaryKey() // Column<Int>     val name = varchar("name", 50) // Column<String>  }
  • 29. Exposed - SQL DSL val munichId = Cities.insert {     it[name] = "Munich" } get Cities.id  Cities.insert { it[name] = "Prague" }  Users.insert {      it[id] = "andrey"      it[name] = "Andrey"      it[cityId] = saintPetersburgId  } Users.insert {      it[id] = "sergey"     it[name] = "Sergey"      it[cityId] = munichId }
  • 30. Exposed - SQL DSL - Join (Users innerJoin Cities)     .slice(Users.name, Cities.name)     .select {         (Users.id.eq("andrey") or Users.name.eq("Sergey")) and         Users.id.eq("sergey") and Users.cityId.eq(Cities.id)     }     .forEach {          println("${it[Users.name]} lives in ${it[Cities.name]}")     }
  • 31. Exposed - SQL DSL - Join 2 ((Cities innerJoin Users)     .slice(Cities.name, Users.id.count())     .selectAll()     .groupBy(Cities.name))     .forEach {         val cityName = it[Cities.name]         val userCount = it[Users.id.count()]         if (userCount > 0) {             println("$userCount user(s) live(s) in $cityName")         } else {              println("Nobody lives in $cityName")         }      }
  • 32. Exposed - DAO object Users : IntIdTable() {     val name = varchar("name", 50).index()     val city = reference("city", Cities)     val age = integer("age") } object Cities: IntIdTable() {      val name = varchar("name", 50) } Schema Definition class User(id: EntityID<Int>) : IntEntity(id){     companion object : IntEntityClass<User>(Users)     var name by Users.name     var city by City referencedOn Users.city     var age by Users.age  } class City(id: EntityID<Int>) : IntEntity(id) {     companion object : IntEntityClass<City>(Cities)     var name by Cities.name     val users by User referrersOn Users.city  } Entity Definition
  • 33. Exposed - DAO Usage val munich = City.new {     name = "Munich" } User.new {     name = "a"     city = munich     age = 5 } User.new {     name = "b"     city = munich     age = 27 } munich.users.joinToString { it.name } User.find { Users.age.between(18, 60) } OneTo Many All user’s name in Munich
  • 34. Conclusion • Already legacy database exists ? Use only Java • jOOQ or requery • Scala only ? -> Slick • Kotlin only ? -> requery, Exposed • No matter language? -> requery • Need Reactive programming? -> • requery with kotlinx-requery • kotlinx-rxjava2-jdbc ( we will open March )