SlideShare ist ein Scribd-Unternehmen logo
1 von 35
Downloaden Sie, um offline zu lesen
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!

Weitere ähnliche Inhalte

Was ist angesagt?

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
 

Was ist angesagt? (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
 

Ähnlich wie 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
 

Ähnlich wie 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 ...
 

Mehr von 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
 

Mehr von 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
 

Kürzlich hochgeladen

How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceanilsa9823
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 

Kürzlich hochgeladen (20)

How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 

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 )