Download presentation
Presentation is loading. Please wait.
Published byQuentin Walker Modified over 8 years ago
1
Patterns and Anti-Patterns in Hibernate Patrycja Wegrzynowicz CTO, Yonita, Inc. CTO, Yon Labs and Yon Consulting, LLC
2
About me Past 10+ years of practical experience as software developer, architect, and head of software R&D PhD in Computer Science (automated code analysis) Speaker at JavaOne, JavaZone, Devoxx, Jazoon, OOPSLA, and others Present Founder and CTO of Yonita Inc. and Yon Consulting Bridge the gap between the industry and the academia Future Who cares? Seize the day!
3
Agenda Transactional issues Break Object-oriented issues Break Performance issues Break Automated detection
4
Usage Aspects of Hibernate Architecture Object- Oriented Design Relational DB Design Programming
5
CaveatEmptor Demo Java Persistence with Hibernate Christian Bauer Gavin King CaveatEmptor Demo in the book Simple auction system
6
TRANSACTIONAL ISSUES
7
First and Foremost, Correctness Warranty of correctness A piece of code always produces an expected result Scenarios Various inputs Concurrency Time line
8
Is CaveatEmptor Correct? transaction
9
CaveatEmptor – Concurrent Scenario Thread A – new bid 9999 // begin transaction // two bids in the db: 100, 124 Bid curMinBid = itemDAO.getMinBid(itemId); Bid curMaxBid = itemDAO.getMaxBid(itemId); // curMaxBid = 124 // get locked item // item with two bids: 100, 124 // curMaxBid = 124 Item item = itemDAO.findById(itemId, true); Bid newBid = item.placeBid(…, newAmount, curMaxBid, curMinBid); // commit transaction Thread B – new bid 1000 // begin transaction // two bids in db: 100, 124 Bid curMinBid = itemDAO.getMinBid(itemId); Bid curMaxBid = itemDAO.getMaxBid(itemId); // curMaxBid = 124 // get locked item // item with three bids: 100, 124, 9999 // but curMaxBid = 124 Item item = itemDAO.findById(itemId, true); Bid newBid = item.placeBid(…, newAmount, curMaxBid, curMinBid); // commit transaction Two bids in the database: 100, 124 12 34 successful bid: 9999 successful bid: 1000
10
How to Fix It? REPEATABLE_READS SERIALIZABLE HIBERNATE VERSIONING YES NO YES
11
CaveatEmptor – Hibernate Versioning Thread A – new bid 9999 // begin transaction // two bids in the db: 100, 124 Bid curMinBid = itemDAO.getMinBid(itemId); Bid curMaxBid = itemDAO.getMaxBid(itemId); // curMaxBid = 124 // get item (version 1) // item with two bids: 100, 124 // curMaxBid = 124 Item item = itemDAO.findById(itemId, true); Bid newBid = item.placeBid(…, newAmount, curMaxBid, curMinBid); // commit transaction (version 2) Thread B – new bid 1000 // begin transaction // two bids in db: 100, 124 Bid curMinBid = itemDAO.getMinBid(itemId); Bid curMaxBid = itemDAO.getMaxBid(itemId); // curMaxBid = 124 // get item (version 2) // item with three bids: 100, 124, 9999 // but curMaxBid = 124 Item item = itemDAO.findById(itemId, true); Bid newBid = item.placeBid(…, newAmount, curMaxBid, curMinBid); // commit transaction (version 3) Two bids in the database: 100, 124 12 34 successful bid: 9999 successful bid: 1000
12
CaveatEmptor – Repeatable Reads Thread A – new bid 9999 // begin transaction // two bids in the db: 100, 124 Bid curMinBid = itemDAO.getMinBid(itemId); Bid curMaxBid = itemDAO.getMaxBid(itemId); // curMaxBid = 124 // get item (version 1) // item with two bids: 100, 124 // curMaxBid = 124 Item item = itemDAO.findById(itemId, true); Bid newBid = item.placeBid(…, newAmount, curMaxBid, curMinBid); // commit transaction (version 2) Thread B – new bid 1000 // begin transaction // two bids in db: 100, 124 Bid curMinBid = itemDAO.getMinBid(itemId); Bid curMaxBid = itemDAO.getMaxBid(itemId); // curMaxBid = 124 // get item (version 2) // item with two bids loaded: 100, 124 // but curMaxBid = 124 Item item = itemDAO.findById(itemId, true); Bid newBid = item.placeBid(…, newAmount, curMaxBid, curMinBid); // commit transaction (version 3) Two bids in the database: 100, 124 12 34 successful bid: 9999 successful bid: 1000
13
CaveatEmptor - Repeatable Reads Even worse MySQL takes a snapshot of the database at the moment of the first query
14
CaveatEmptor - Serializable SERIALIZABLE works fine All transactions occur in a completely isolated fashion; i.e., as if all transactions in the system had executed serially, one after the other Snapshot isolation or lock-based concurrency control (read/write locks released at the end of a transaction, range-locks) What about performance? Can you imagine eBay working this way?
15
CaveatEmptor - Re-Ordering
16
Item class Represents item and auction; has the list of bids Why to inject min and max bids (internal state) to an item? Back to OO Principles Objects should contain their internal state
17
Alternative Approaches Calculate maximum in Java Safe, but requires loading of all the bids Keep track of the winning bid Manual tracking, but with encapsulation Db denormalized, but fast Utilize custom mappings with custom queries, laziness, order or where clauses Db normalized, as fast as the present code
18
18 Alternative Aproaches Inverse Mappings with Embedded Queries <set name=„maxBids" inverse="true" lazy=„true"> > Automated object state –Encapsulation > Inverse –Makes use of present relations –Normalized form > Lazy –Loaded on the first access > Custom queries –SQL –Use order-by and where if they are enough
19
Puzzle #1 getItemMaxBid select b from Bid b where b.amount.value = (select max(b.amount.value) from Bid b where b.item.id = :itemid)
20
Puzzle #1 getItemMaxBid – Hint Item #1 Bid $100 Bid $125 Bid $150 Item #2 Bid $20 Bid $125 select b from Bid b where b.amount.value = (select max(b.amount.value) from Bid b where b.item.id = :itemid)
21
Puzzle #1 getItemMaxBid – Answer Item #1 Bid $100 Bid $125 Bid $150 Item #2 Bid $20 Bid $125 getItemMaxBid(Item#2) Item #1 Bid $125 Item #2 Bid $125 select b from Bid b where b.amount.value = (select max(b.amount.value) from Bid b where b.item.id = :itemid)
22
Puzzle #1 getItemMaxBid – Fixed Item #1 Bid $100 Bid $125 Bid $150 Item #2 Bid $20 Bid $125 getItemMaxBid(Item#2) Item #2 Bid $125 select b from Bid b where b.amount.value = (select max(b.amount.value) from Bid b where b.item.id = :itemid) – and b.item.id = :itemid
23
Puzzle #2 placeBid
24
Puzzle #2 placeBid – Hint
25
Puzzle #2 placeBid – Fixed >=>=
26
OBJECT-ORIENTED ISSUES
27
What is OO about? Basic Principles Data abstraction = data + behavior Encapsulation, inheritance, polimorphism Advanced Principles (SOLID) Single Responsibility Principle Open/Closed Principle Liskov Substitution Principle Interface Segregation Principle Dependency Inversion Principle
28
[…] Is This a Good OO Model?
29
[…] Anemic Domain Model! Is This a Good OO Model?
30
Rich OO Model – CaveatEmptor […]
31
CaveatEmptor – A Closer Look
32
We Need Encapsulation! We can add to the mutable list whatever we like. We can add a bid to the item with a different item reference.
33
Without Encapsulation, Business Methods Are Only Lipstick on a Pig
34
Exposed Structure Results in Bad Things Inconsistent state of objects The winning bid for an item which is not maximal The winning bid added after the auction ended Basically, we cannot trust our data! Various Bugs Null pointer exceptions Nasty bugs (unexpected nulls, consider embedded objects!) Too much code Duplicated code, defensive code, spaghetti code
35
Practices to Code for Encapsulation Restrive Access Modifiers private, package, protected fields, getters, setters used by hibernate or to manage referential integrity hibernate is able to deal with any access modifiers (even private!) of the members of a class
36
Practices to Code for Encapsulation Consistent Management of Internal State All roads lead to Rome // custom example! public Item(MonetaryAmount initialPrice) { // beware of polymorphic calls in constructors // it’s better to use a private _setInitialPrice from both the setter and ctr setInitialPrice(initialPrice); } public void setInitialPrice(MonetaryAmount initialPrice) { if (initialPrice == null) throw new IllegalArgumentException(„initial price cant be null”); this.initialPrice = initialPrice; }
37
Practices to Code for Encapsulation Do Not Expose Mutable Internal State Problems mainly in the case of Date and Collection hierarchies return date; // Date return bids; // List Uncontrolled changes to the internal state of an object Defensive copying return new Date(created.getTime()); return new ArrayList(bids); Inefficient for collections – we force the retrieval of the bids from the database Immutable return Collections.unmodifiableList(bids); Inefficient for persistent collections mapped by property as dirty checking compares collections by identity
38
38 Practices to Code for Encapsulation Immutable Collection Returned >Dirty checking compares identity of collections –Additional statements issued –Embedded objects – recreation of the collection –List of entities – all entities updated >Practices –Internally, do not create new collections, reuse the one retrieved –Use field mapping, or –Use different accessors for public access and hibernate access
39
Practices to Code for Encapsulation Business first First business methods, than accessors Restrictive access modifiers Hibernate can deal with private/package/protected Don't expose mutable internal state Problems mainly in the case of Date and Collections return date; // Date return bids; // List Uncontrolled changes to the internal state of an object
40
Puzzle #3 Immutable List
41
Puzzle #3 Immutable List - Hint item.setBids(item.getBids())?
42
Puzzle #3 Immutable List - Answer item.setBids(item.getBids())? The answer: bids = empty list
43
PERFORMANCE ISSUES
44
This is Java.
45
Is Java Slow? On most Intels Java is as fast or faster than C The Gaia Satellie and Data Processing William O’Mullane from ESAC Jazoon 2010
46
Is Hibernate Slow? Sometimes… Depending on usage scenarios
47
Puzzle #4 Standard Collection Mapping
50
Puzzle #5 Immutable Collections
51
Puzzle #5 Immutable Collections – Hint
52
Puzzle #5 Immutable Collection
53
Inheritance Strategies > Table per class hierarchy –One table > Table per subclass –Four tables > Table per concrete class –Two tables A > B > C D
54
Inheritance Strategies in Hibernate ConstraintsDirect AccessPolymorphism Table per Class Hierarchy Sometimes impossible to add db constrains (e.g. not null) Fast Polymorphic search Polymorphic relations Table per Subclass Constraints possibleSlower (joins) Polymorphic search Polymorphic relations Table per Concrete Class Constraints possibleFast Polymorphic search with unions or N queries + ++ ++ + ! ! ÷
55
AUTOMATED DETECTION OF HIBERNATE ISSUES
56
Code Level
57
Code Level Analysis
59
Automated Detection of Code Issues + Automated code analysis Definions of transactional, security, performance anti- patterns
60
Semantic Code Query System Code query systems Explore relationships among program elements Structural and call-related predicates CodeQuest, JQuery Semantic code query systems Focus on behavior (in-depth data flow analysis) Behavioral predicates in addition to structural ones D-CUBED – my PhD thesis (focus on design patterns) Yonita – rewrite + queries
61
Yonita Automated code analysis Semantic code query system Focus on behavior, not only structure Metamodel of a program: instances, structure, behaviour (calls, input/output values, execution paths) Definitions of various issues/anti-patterns Catalog of issues Transactions, object-oriented design, security, performance, multithreading
62
How does Yonita work? Analyses Parser Store Query Bytecode Sources asm, Recoder analyses: structural, call flow, data flow transitive closures relational (MySQL) or deductive (XSB) database SQL or Prolog (anti-)patterns bugs vulnerabilities...
63
Metamodel Structural elements Very similar to CodeQuest and Jquery Statements Instances Symbolic instances Behavioral predicates supporting call and data flows Output and input values Assignments
64
Instances Null New This Parameter Exception Multiple Return Instance Param Instance This Instance New Instance Null Instance Except. Instance … … …
65
Summary Proper usage of hibernate is tricky Transactional issues and correctness of code under various scenarios Maintanability and basic object-oriented principles Efficiency of code and mappings Automatization can help
66
Contact Patrycja patrycja@YonLabs.com twitter.com/YonLabs Yonita http://www.Yonita.com http://www.YonLabs.com http://www.YonConsulting.com
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.