SlideShare a Scribd company logo
Performance Anti-Patterns
 in Hibernate
 Patrycja Wegrzynowicz
 CTO
 Yonita, Inc.


Tuesday, November 22, 2011
About Me
   • 10+ years of professional experience
   • PhD in Computer Science
         –Patterns and anti-patterns, static and dynamic code
          analysis, language semantics, compiler design
   • Active author and speaker
         –JavaOne, Devoxx, JavaZone, Jazoon, OOPSLA, ASE...
   • CTO of Yonita, Inc.
         –Bridge the gap between the industry and the academia
         –Automated defects detection and optimization
         –Performance, security, concurrency, databases
   • Twitter @yonlabs                                           2

Tuesday, November 22, 2011
Agenda


   • 4 puzzles
         –Short program with curious behavior
         –Question to you (multiple choice)
         –Mystery revealed
         –Lessons learned
   • 7 performance anti-patterns
         –Description, consequences, solutions


                                                 3

Tuesday, November 22, 2011
Disclaimer




                             I do think Hibernate is a great tool!




                                                                     4

Tuesday, November 22, 2011
5

Tuesday, November 22, 2011
5

Tuesday, November 22, 2011
5

Tuesday, November 22, 2011
Puzzle #1
                                 Less Is More




Tuesday, November 22, 2011
Who knows CaveatEmptor app?




                                                           7

Tuesday, November 22, 2011
Who’s read Java Persistence
                                   with Hibernate?




                                                           8

Tuesday, November 22, 2011
CaveatEmptor



   • Demo application from
     ‘Java Persistence with
     Hibernate’
   • Simple auction system



                              9

Tuesday, November 22, 2011
I’m Gonna Win This Auction!


   public class PlaceBidAction implements Action {
      // invoked in a new transaction
      public String execute(Map even) {
          // ...
          Bid currentMinBid = itemDAO.getMinBid(itemId);
          Bid currentMaxBid = itemDAO.getMaxBid(itemId);

                // uses load with Lock.UPGRADE
                Item item = itemDAO.findById(itemId, true);
                Bid newBid = item.placeBid(userDAO.findById(userId, false),
                                   newAmount,
                                   currentMaxBid,
                                   currentMinBid);
                // ...
       }
   }




                                                                              10

Tuesday, November 22, 2011
What’s the Problem?

                                                              (a) None (code is correct)
                                                              (b) Transaction/lock mgmt
   public class PlaceBidAction implements Action {            (c) Exception thrown
      // invoked in a new transaction                         (d) None of the above
      public String execute(Map even) {
          // ...
          Bid currentMinBid = itemDAO.getMinBid(itemId);
          Bid currentMaxBid = itemDAO.getMaxBid(itemId);

                // uses load with Lock.UPGRADE
                Item item = itemDAO.findById(itemId, true);
                Bid newBid = item.placeBid(userDAO.findById(userId, false),
                                   newAmount,
                                   currentMaxBid,
                                   currentMinBid);
                // ...
       }
   }




                                                                                           11

Tuesday, November 22, 2011
What’s the Problem?

   (a) None (the code is correct)
   (b) Transaction/Lock management
   (c) Exception thrown
   (d) None of the above




       The bids can change between calling getMaxBid
       and locking the item.
                                                   12

Tuesday, November 22, 2011
Another Look


   public class PlaceBidAction implements Action {
       // invoked in a new transaction
       public String execute(Map even) {
          // ...
          Bid currentMinBid = itemDAO.getMinBid(itemId);
          Bid currentMaxBid = itemDAO.getMaxBid(itemId);
          // here, the bids can be modified by a different transaction
          // uses load with Lock.UPGRADE
          Item item = itemDAO.findById(itemId, true);
          Bid newBid = item.placeBid(userDAO.findById(userId, false),
                             newAmount,
                             currentMaxBid,
                             currentMinBid);
          // ...
     }
   }




                                                                         13

Tuesday, November 22, 2011
2 Users and Item with 2 Bids
             Thread A (new amount 100)   Thread B (new amount 30)

                   (1)
   // begin transaction
   // item with 2 bids: 10,20
   Bid curMax = dao.getMaxBid(id);
   // curMax = 20




                                                                    14

Tuesday, November 22, 2011
2 Users and Item with 2 Bids
             Thread A (new amount 100)        Thread B (new amount 30)

                   (1)                                   (2)
   // begin transaction                  // begin transaction
   // item with 2 bids: 10,20            // item with 2 bids: 10,20
   Bid curMax = dao.getMaxBid(id);       Bid curMax = dao.getMaxBid(id);
   // curMax = 20                        // curMax = 20




                                                                           15

Tuesday, November 22, 2011
2 Users and Item with 2 Bids
             Thread A (new amount 100)         Thread B (new amount 30)

                   (1)                                    (2)
   // begin transaction                   // begin transaction
   // item with 2 bids: 10,20             // item with 2 bids: 10,20
   Bid curMax = dao.getMaxBid(id);        Bid curMax = dao.getMaxBid(id);
   // curMax = 20                         // curMax = 20

                   (3)
   // item with 2 bids: 10,20
   // Lock.UPGRADE
   Item item = dao.findById(id,true);
   Bid newBid = item.placeBid(...,
                newAmount,
                curMax, ...);
   // commit transaction
   // item with 3 bids: 10,20,100

                    Successful bid: 100




                                                                            16

Tuesday, November 22, 2011
2 Users and Item with 2 Bids
             Thread A (new amount 100)         Thread B (new amount 30)

                   (1)                                    (2)
   // begin transaction                   // begin transaction
   // item with 2 bids: 10,20             // item with 2 bids: 10,20
   Bid curMax = dao.getMaxBid(id);        Bid curMax = dao.getMaxBid(id);
   // curMax = 20                         // curMax = 20

                   (3)                                    (4)
   // item with 2 bids: 10,20             // item with 3 bids: 10,20,100
   // Lock.UPGRADE                        // Lock.UPGRADE
   Item item = dao.findById(id,true);     Item item = dao.findById(id,true);
   Bid newBid = item.placeBid(...,        Bid newBid = item.placeBid(...,
                newAmount,                             newAmount,
                curMax, ...);                          curMax, ...);
   // commit transaction                  // commit transaction
   // item with 3 bids: 10,20,100         // item with 4 bids: 10,20,100,30

                    Successful bid: 100           Successful bid: 30




                                                                               17

Tuesday, November 22, 2011
How To Fix It?


   public class PlaceBidAction implements Action {
      // invoked in a new transaction
      public String execute(Map even) {
          // ...
          Bid currentMinBid = itemDAO.getMinBid(itemId);
          Bid currentMaxBid = itemDAO.getMaxBid(itemId);

                // uses load with Lock.UPGRADE
                Item item = itemDAO.findById(itemId, true);
                Bid newBid = item.placeBid(userDAO.findById(userId, false),
                                   newAmount,
                                   currentMaxBid,
                                   currentMinBid);
                // ...
       }
   }




                                                                              18

Tuesday, November 22, 2011
How To Fix It?
                                                                          version and
                                                                       optimistic locking

   public class PlaceBidAction implements Action {
      // invoked in a new transaction
      public String execute(Map even) {
          // ...
          Bid currentMinBid = itemDAO.getMinBid(itemId);
          Bid currentMaxBid = itemDAO.getMaxBid(itemId);

                // uses load with Lock.UPGRADE
                Item item = itemDAO.findById(itemId, true);
                Bid newBid = item.placeBid(userDAO.findById(userId, false),
                                   newAmount,
                                   currentMaxBid,
                                   currentMinBid);
                // ...
       }
   }




                                                                                            18

Tuesday, November 22, 2011
How To Fix It?
                                                                          version and
                                                                              NO
                                                                       optimistic locking

   public class PlaceBidAction implements Action {
      // invoked in a new transaction
      public String execute(Map even) {
          // ...
          Bid currentMinBid = itemDAO.getMinBid(itemId);
          Bid currentMaxBid = itemDAO.getMaxBid(itemId);

                // uses load with Lock.UPGRADE
                Item item = itemDAO.findById(itemId, true);
                Bid newBid = item.placeBid(userDAO.findById(userId, false),
                                   newAmount,
                                   currentMaxBid,
                                   currentMinBid);
                // ...
       }
   }




                                                                                            18

Tuesday, November 22, 2011
How To Fix It?
                                                                          version and
                                                                              NO
                                                                       optimistic locking

                                                                         REPEATABLE
   public class PlaceBidAction implements Action {
      // invoked in a new transaction                                      READS
      public String execute(Map even) {
          // ...
          Bid currentMinBid = itemDAO.getMinBid(itemId);
          Bid currentMaxBid = itemDAO.getMaxBid(itemId);

                // uses load with Lock.UPGRADE
                Item item = itemDAO.findById(itemId, true);
                Bid newBid = item.placeBid(userDAO.findById(userId, false),
                                   newAmount,
                                   currentMaxBid,
                                   currentMinBid);
                // ...
       }
   }




                                                                                            18

Tuesday, November 22, 2011
How To Fix It?
                                                                          version and
                                                                              NO
                                                                       optimistic locking

                                                                         REPEATABLE
   public class PlaceBidAction implements Action {
      // invoked in a new transaction                                      READS
      public String execute(Map even) {
          // ...
                                                                        SERIALIZABLE
          Bid currentMinBid = itemDAO.getMinBid(itemId);
          Bid currentMaxBid = itemDAO.getMaxBid(itemId);

                // uses load with Lock.UPGRADE
                Item item = itemDAO.findById(itemId, true);
                Bid newBid = item.placeBid(userDAO.findById(userId, false),
                                   newAmount,
                                   currentMaxBid,
                                   currentMinBid);
                // ...
       }
   }




                                                                                            18

Tuesday, November 22, 2011
How To Fix It?
                                                                          version and
                                                                              NO
                                                                       optimistic locking

                                                                         REPEATABLE
   public class PlaceBidAction implements Action {                           NO
      // invoked in a new transaction                                      READS
      public String execute(Map even) {
          // ...
                                                                        SERIALIZABLE
          Bid currentMinBid = itemDAO.getMinBid(itemId);
          Bid currentMaxBid = itemDAO.getMaxBid(itemId);

                // uses load with Lock.UPGRADE
                Item item = itemDAO.findById(itemId, true);
                Bid newBid = item.placeBid(userDAO.findById(userId, false),
                                   newAmount,
                                   currentMaxBid,
                                   currentMinBid);
                // ...
       }
   }




                                                                                            18

Tuesday, November 22, 2011
How To Fix It?
                                                                          version and
                                                                              NO
                                                                       optimistic locking

                                                                         REPEATABLE
   public class PlaceBidAction implements Action {                           NO
      // invoked in a new transaction                                      READS
      public String execute(Map even) {
          // ...
                                                                        SERIALIZABLE
                                                                            YES
          Bid currentMinBid = itemDAO.getMinBid(itemId);
          Bid currentMaxBid = itemDAO.getMaxBid(itemId);

                // uses load with Lock.UPGRADE
                Item item = itemDAO.findById(itemId, true);
                Bid newBid = item.placeBid(userDAO.findById(userId, false),
                                   newAmount,
                                   currentMaxBid,
                                   currentMinBid);
                // ...
       }
   }




                                                                                            18

Tuesday, November 22, 2011
How To Fix It?
                                                                          version and
                                                                              NO
                                                                       optimistic locking

                                                                         REPEATABLE
   public class PlaceBidAction implements Action {                           NO
      // invoked in a new transaction                                      READS
      public String execute(Map even) {
          // ...
                                                                        SERIALIZABLE
                                                                            YES
          Bid currentMinBid = itemDAO.getMinBid(itemId);
          Bid currentMaxBid = itemDAO.getMaxBid(itemId);               move lock before
                // uses load with Lock.UPGRADE                           getMinBid/
                Item item = itemDAO.findById(itemId, true);              getMaxBid
                Bid newBid = item.placeBid(userDAO.findById(userId, false),
                                   newAmount,
                                   currentMaxBid,
                                   currentMinBid);
                // ...
       }
   }




                                                                                            18

Tuesday, November 22, 2011
How To Fix It?
                                                                          version and
                                                                              NO
                                                                       optimistic locking

                                                                         REPEATABLE
   public class PlaceBidAction implements Action {                           NO
      // invoked in a new transaction                                      READS
      public String execute(Map even) {
          // ...
                                                                        SERIALIZABLE
                                                                            YES
          Bid currentMinBid = itemDAO.getMinBid(itemId);
          Bid currentMaxBid = itemDAO.getMaxBid(itemId);               move lock before
                // uses load with Lock.UPGRADE                           getMinBid/
                                                                            YES
                Item item = itemDAO.findById(itemId, true);              getMaxBid
                Bid newBid = item.placeBid(userDAO.findById(userId, false),
                                   newAmount,
                                   currentMaxBid,
                                   currentMinBid);
                // ...
       }
   }




                                                                                            18

Tuesday, November 22, 2011
How To Fix It?
                                                                          version and
                                                                              NO
                                                                       optimistic locking

                                                                        REPEATABLE
   public class PlaceBidAction implements Action {                          NO
      // invoked in a new transaction                                     READS
      public String execute(Map even) {
          // ...
                                                                        SERIALIZABLE
                                                                            YES
          Bid currentMinBid = itemDAO.getMinBid(itemId);
          Bid currentMaxBid = itemDAO.getMaxBid(itemId);               move lock before
                // uses load with Lock.UPGRADE                           getMinBid/
                                                                            YES
                Item item = itemDAO.findById(itemId, true);              getMaxBid
                Bid newBid = item.placeBid(userDAO.findById(userId, false),
                                   newAmount,
                                   currentMaxBid,                           different
                                   currentMinBid);                        object model
                // ...
       }
   }




                                                                                            18

Tuesday, November 22, 2011
How To Fix It?
                                                                          version and
                                                                              NO
                                                                       optimistic locking

                                                                        REPEATABLE
   public class PlaceBidAction implements Action {                          NO
      // invoked in a new transaction                                     READS
      public String execute(Map even) {
          // ...
                                                                        SERIALIZABLE
                                                                            YES
          Bid currentMinBid = itemDAO.getMinBid(itemId);
          Bid currentMaxBid = itemDAO.getMaxBid(itemId);               move lock before
                // uses load with Lock.UPGRADE                           getMinBid/
                                                                            YES
                Item item = itemDAO.findById(itemId, true);              getMaxBid
                Bid newBid = item.placeBid(userDAO.findById(userId, false),
                                   newAmount,
                                   currentMaxBid,                           different
                                                                              YES
                                   currentMinBid);                        object model
                // ...
       }
   }




                                                                                            18

Tuesday, November 22, 2011
How To Fix It?
                                                                          version and
                                                                              NO
                                                                       optimistic locking

                                                                        REPEATABLE
   public class PlaceBidAction implements Action {                          NO
      // invoked in a new transaction                                     READS
      public String execute(Map even) {
          // ...
                                                                        SERIALIZABLE
                                                                            YES
          Bid currentMinBid = itemDAO.getMinBid(itemId);
          Bid currentMaxBid = itemDAO.getMaxBid(itemId);               move lock before
                // uses load with Lock.UPGRADE                           getMinBid/
                                                                            YES
                Item item = itemDAO.findById(itemId, true);              getMaxBid
                Bid newBid = item.placeBid(userDAO.findById(userId, false),
                                   newAmount,
                                   currentMaxBid,                           different
                                                                              YES
                                   currentMinBid);                        object model
                // ...
       }
   }                                                                         Java
                                                                         synchronized


                                                                                            18

Tuesday, November 22, 2011
How To Fix It?
                                                                          version and
                                                                              NO
                                                                       optimistic locking

                                                                        REPEATABLE
   public class PlaceBidAction implements Action {                          NO
      // invoked in a new transaction                                     READS
      public String execute(Map even) {
          // ...
                                                                        SERIALIZABLE
                                                                            YES
          Bid currentMinBid = itemDAO.getMinBid(itemId);
          Bid currentMaxBid = itemDAO.getMaxBid(itemId);               move lock before
                // uses load with Lock.UPGRADE                           getMinBid/
                                                                            YES
                Item item = itemDAO.findById(itemId, true);              getMaxBid
                Bid newBid = item.placeBid(userDAO.findById(userId, false),
                                   newAmount,
                                   currentMaxBid,                           different
                                                                              YES
                                   currentMinBid);                        object model
                // ...
       }
                                                                             Java
   }                                                                         YES
                                                                         synchronized


                                                                                            18

Tuesday, November 22, 2011
Lessons Learned

   • Nobody’s perfect ;-)
   • ACID is only a theory
         –Simple transaction interceptor/annotation often is not
          enough
         –Query order does matter
         –Learn more about locks and transaction isolation levels
   • Premature optimization is the root of all evil
         –Performance Anti-Pattern #1


                                                                19

Tuesday, November 22, 2011
Performance Lessons



   • Object model
   • Usage patterns
         –Concurrent users
         –Data volume
   • Transaction and locking management


                                          20

Tuesday, November 22, 2011
Puzzle #2
                                Heads of Hydra




Tuesday, November 22, 2011
Heads of Hydra

   @Entity
   public class Hydra {
      private Long id;
      private List<Head> heads = new ArrayList<Head>();

         @Id @GeneratedValue
         public Long getId() {...}
         protected void setId() {...}
         @OneToMany(cascade=CascadeType.ALL)
         public List<Head> getHeads() {
            return Collections.unmodifiableList(heads);
         }
         protected void setHeads(List<Head> heads) {...}
   }

   // creates and persists the hydra with 3 heads

   // new EntityManager and new transaction
   Hydra found = em.find(Hydra.class, hydra.getId());



                                                           22

Tuesday, November 22, 2011
How Many Queries in 2nd Tx?
                                                           (a) 1 select
                                                           (b) 2 selects
   @Entity                                                 (c) 1+3 selects
   public class Hydra {
      private Long id;                                     (d) 2 selects, 1 delete, 3
      private List<Head> heads = new ArrayList<Head>();    inserts
                                                           (e) None of the above
         @Id @GeneratedValue
         public Long getId() {...}
         protected void setId() {...}
         @OneToMany(cascade=CascadeType.ALL)
         public List<Head> getHeads() {
            return Collections.unmodifiableList(heads);
         }
         protected void setHeads(List<Head> heads) {...}
   }

   // creates and persists the hydra with 3 heads

   // new EntityManager and new transaction
   Hydra found = em.find(Hydra.class, hydra.getId());



                                                                                        23

Tuesday, November 22, 2011
How Many Queries in 2nd Tx?
   (a) 1 select
   (b) 2 selects
   (c) 1+3 selects
   (d) 2 selects, 1 delete, 3 inserts
   (e) None of the above



       During commit hibernate checks whether the
       collection property is dirty (needs to be re-
       created) by comparing Java identities (object
       references).                                    24

Tuesday, November 22, 2011
Another Look

   @Entity
   public class Hydra {
      private Long id;
      private List<Head> heads = new ArrayList<Head>();

         @Id @GeneratedValue
         public Long getId() {...}
         protected void setId() {...}
         @OneToMany(cascade=CascadeType.ALL)
         public List<Head> getHeads() {
            return Collections.unmodifiableList(heads);
         }
         protected void setHeads(List<Head> heads) {...}
   }

   // creates and persists hydra with three heads

   // new EntityManager and new transaction
   // during find only 1 select (hydra)
   Hydra found = em.find(Hydra.class, hydra.getId());
   // during commit 1 select (heads),1 delete (heads),3 inserts (heads)


                                                                          25

Tuesday, November 22, 2011
How To Fix It?

  @Entity
  public class Hydra {
     @Id @GeneratedValue
     private Long id;
     @OneToMany(cascade=CascadeType.ALL)
     private List<Head> heads = new ArrayList<Head>();

         public Long getId() {...}
         protected void setId() {...}
         public List<Head> getHeads() {
            return Collections.unmodifiableList(heads);
         }
         protected void setHeads(List<Head> heads) {...}
  }

  // creates and persists hydra with three heads

  // new EntityManager and new transaction
  Hydra found = em.find(Hydra.class, hydra.getId());



                                                           26

Tuesday, November 22, 2011
Lessons Learned




   • Expect unexpected ;-)
   • Prefer field access mappings
   • And...




                                    27

Tuesday, November 22, 2011
Anti-Pattern #2
                             Lost Collection Proxy on Owning Side




Tuesday, November 22, 2011
Lost Collection Proxy


   • Description
         –On the owning side of an association, we assign a new
          collection object to a persistent field/property overriding
          a collection proxy returned by hibernate
   • Consequences
         –The entire collection is re-created: one delete to
          remove all elements and then many element inserts


                                                                   29

Tuesday, November 22, 2011
Lost Collection Proxy - Example

   @Entity
   public class Hydra {
      @Id @GeneratedValue
      private Long id;
      @OneToMany(cascade=CascadeType.ALL)
      private List<Head> heads = new ArrayList<Head>();

         public Long getId() {...}
         protected void setId() {...}
         public List<Head> getHeads() {
            return heads;
         }
         public void setHeads(List<Head> heads) {
            this.heads = heads;
         }
   }




                                                          30

Tuesday, November 22, 2011
Lost Collection Proxy - Solution

   • Operate on collection objects returned by
     hibernate
         –In most cases it’s a much more efficient solution
   • Unless you know what you’re doing
         –It might be performance-wise in some cases to re-
          create the entire collection (bulk delete)
         –However, it’s the place when hibernate could do better,
          having all required data available:
               • Original size, added and removed elements
               • Min(#added + #removed, 1 + #size - #removed + #added)
                                                                         31

Tuesday, November 22, 2011
Puzzle #3
                             Fashionable Developer




Tuesday, November 22, 2011
Fashionable Developer
   @Entity
   public class Developer {
      @Id @GeneratedValue
      private Long id;
      private String mainTechnology;

         public boolean likesMainTechnology() {
            return "hibernate".equalsIgnoreCase(mainTechnology);
         }
   }
   // creates and persists a developer that uses hibernate as mainTechnology

   // new EntityManager and new transaction
   Developer dev = em.find(Developer.class, id);
   boolean foundCoolStuff = false;
   for (String tech : new String[]{"HTML5", "Android", "Scala"}) {
      dev.setMainTechnology(tech);
      // othersAreUsingIt:
      // select count(*) from Developer where mainTechnology = ? and id != ?
      if (othersAreUsingIt(tech, dev) && dev.likesMainTechnology()) {
          foundCoolStuff = true; break;
      }
   }
   if (!foundCoolStuff) {
      // still use hibernate
      dev.setMainTechnology("hibernate");
                                                                               33
   }
Tuesday, November 22, 2011
How Many Queries in 2nd Tx?
   @Entity
   public class Developer {                                (a) 2 select
      @Id @GeneratedValue                                  (b) 4 selects
      private Long id;
      private String mainTechnology;                       (c) 4 selects, 1 update
                                                           (d) 4 selects, 4 updates
         public boolean likesMainTechnology() {
                                                           (e) None of the above
            return "hibernate".equalsIgnoreCase(mainTechnology);
         }
   }
   // creates and persists a developer that uses hibernate as mainTechnology

   // new EntityManager and new transaction
   Developer dev = em.find(Developer.class, id);
   boolean foundCoolStuff = false;
   for (String tech : new String[]{"HTML5", "Android", "Scala"}) {
      dev.setMainTechnology(tech);
      // othersAreUsingIt:
      // select count(*) from Developer where mainTechnology = ? and id != ?
      if (othersAreUsingIt(tech, dev) && dev.likesMainTechnology()) {
          foundCoolStuff = true; break;
      }
   }
   if (!foundCoolStuff) {
      // still use hibernate
      dev.setMainTechnology("hibernate");
                                                                                      34
   }
Tuesday, November 22, 2011
How Many Queries in 2nd Tx?
   (a) 2 selects
   (b) 4 selects
   (c) 4 selects, 1 update
   (d) 4 selects, 4 inserts
   (e) None of the above



       Hibernate must guarantee correctness of
       executed queries, therefore in certain situations it
       must perform flushes during a transaction.
                                                          35

Tuesday, November 22, 2011
Fashionable Developer
   @Entity
   public class Developer {
      @Id @GeneratedValue
      private Long id;
      private String mainTechnology;                               NO UPDATES
         public boolean likesMainTechnology() {
            return "hibernate".equalsIgnoreCase(mainTechnology);
         }
   }
   // creates and persists a developer that uses hibernate as mainTechnology

   // new EntityManager and new transaction
   Developer dev = em.find(Developer.class, id);
   boolean foundCoolStuff = false;
   for (String tech : new String[]{"HTML5", "Android", "Scala"}) {
      dev.setMainTechnology(tech);
      // othersAreUsingIt:
      // select count(*) from Developer where mainTechnology = ? and id != ?
      if (/*othersAreUsingIt(tech, dev) &&*/ dev.likesMainTechnology()) {
          foundCoolStuff = true; break;
      }
   }
   if (!foundCoolStuff) {
      // still use hibernate
      dev.setMainTechnology("hibernate");
                                                                                36
   }
Tuesday, November 22, 2011
Anti-Pattern #3
                                   Temporary Changes




Tuesday, November 22, 2011
Temporary Changes
   • Description
         –We change the persistent data of an object temporarily to
          test some features
         –In the meantime a database flush occurs triggered, for
          example, by a HQL touching the table
   • Consequences
         –Flushes can be performed during the transaction, not
          only at the commit time
         –Temporary changes persisted into the database
          unnecessarily
   • Solution
         –Plan your business model and processing to avoid
          temporary changes to your persistent data              38

Tuesday, November 22, 2011
Puzzle #4
                                 Plant a Tree




Tuesday, November 22, 2011
Plant a Tree

   @Entity
   public class Forest {
      @Id @GeneratedValue
      private Long id;
      @OneToMany
      Collection<Tree> trees = new HashSet<Tree>();

         public void plantTree(Tree tree) {
            trees.add(tree);
         }
   }

   // creates and persists a forest with 10.000 trees

   // new EntityManager and new transaction
   Tree tree = new Tree(“oak”);
   em.persist(tree);
   Forest forest = em.find(Forest.class, id);
   forest.plantTree(tree);




                                                        40

Tuesday, November 22, 2011
How Many Queries in 2nd Tx?

   @Entity                                              (a) 1 select, 2 inserts
   public class Forest {                                (b) 2 selects, 2 inserts
      @Id @GeneratedValue                               (c) 2 selects, 1 delete,
      private Long id;
      @OneToMany                                        10.000+2 inserts
      Collection<Tree> trees = new HashSet<Tree>();     (d) Even more ;-)
         public void plantTree(Tree tree) {
            trees.add(tree);
         }
   }

   // creates and persists a forest with 10.000 trees

   // new EntityManager and new transaction
   Tree tree = new Tree(“oak”);
   em.persist(tree);
   Forest forest = em.find(Forest.class, id);
   forest.plantTree(tree);




                                                                                   41

Tuesday, November 22, 2011
How Many Queries in 2nd Tx?
   (a) 1 select, 2 inserts
   (b) 2 selects, 2 inserts
   (c) 2 selects, 1 delete, 10.000+2 inserts
   (d) Even more ;-)




       The combination of OneToMany and Collection
       enables a bag semantic. That’s why the collection
       is re-created.                                 42

Tuesday, November 22, 2011
Plant a Tree - Revisited

   @Entity
   public class Orchard {
      @Id @GeneratedValue
      private Long id;
      @OneToMany
      List<Tree> trees = new ArrayList<Tree>();

         public void plantTree(Tree tree) {
            trees.add(tree);
         }
   }

   // creates and persists a forest with 10.000 trees

   // new EntityManager and new transaction
   Tree tree = new Tree(“apple tree”);
   em.persist(tree);
   Orchard orchard = em.find(Orchard.class, id);
   orchard.plantTree(tree);




                                                        43

Tuesday, November 22, 2011
Plant a Tree - Revisited

   @Entity
   public class Orchard {                               STILL BAG SEMANTIC!
      @Id @GeneratedValue
      private Long id;
      @OneToMany
      List<Tree> trees = new ArrayList<Tree>();

         public void plantTree(Tree tree) {
            trees.add(tree);
         }
   }

   // creates and persists a forest with 10.000 trees

   // new EntityManager and new transaction
   Tree tree = new Tree(“apple tree”);
   em.persist(tree);
   Orchard orchard = em.find(Orchard.class, id);
   orchard.plantTree(tree);




                                                                          43

Tuesday, November 22, 2011
Plant a Tree - Revisited

   @Entity
   public class Orchard {                               STILL BAG SEMANTIC!
      @Id @GeneratedValue
      private Long id;                                   Use OrderColumn or
      @OneToMany
      List<Tree> trees = new ArrayList<Tree>();          IndexColumn for list
                                                              semantic.
         public void plantTree(Tree tree) {
            trees.add(tree);
         }
   }

   // creates and persists a forest with 10.000 trees

   // new EntityManager and new transaction
   Tree tree = new Tree(“apple tree”);
   em.persist(tree);
   Orchard orchard = em.find(Orchard.class, id);
   orchard.plantTree(tree);




                                                                                43

Tuesday, November 22, 2011
OneToMany Mapping

                         Seman&c                    Java	
  Type               Annota&on

                                                     java.u3l.Collec3on
                    bag	
  seman3c                       java.u3l.List
                                                                             @ElementCollec3on	
  ||
                                                                          @OneToMany	
  ||	
  @ManyToMany




                     set	
  seman3c                      java.u3l.Set
                                                                             @ElementCollec3on	
  ||
                                                                          @OneToMany	
  ||	
  @ManyToMany


                                                                             (@ElementCollec3on	
  ||
                                                                          @OneToMany	
  ||	
  @ManyToMany)	
  
                     list	
  seman3c                     java.u3l.List                    &&
                                                                                 (@OrderColumn	
  ||	
  
                                                                                  @IndexColumn)
                @OneToMany	
  (no	
  cascade	
  op3on)
                                                                                                                 44

Tuesday, November 22, 2011
OneToMany Mapping

                                            add	
                           remove	
                      update	
  
                                          element                           element                       element

                      bag	
                  re-­‐create:                      re-­‐create:
                                                                                                           1	
  update
                    seman3c           1	
  delete	
  +	
  N	
  inserts 1	
  delete	
  +	
  N	
  inserts


                      set	
                    1	
  insert                       1	
  delete               1	
  update
                    seman3c

                      list	
               1	
  insert	
  +	
  M	
           1	
  delete	
  +	
  M	
  
                                                                                                           1	
  update
                    seman3c                     updates                          updates*


                @OneToMany	
  (no	
  cascade	
  op3on)
                                                                                                                         45

Tuesday, November 22, 2011
OneToMany Mapping

                                            add	
                           remove	
                      update	
  
                                          element                           element                       element

                      bag	
                  re-­‐create:                      re-­‐create:
                                                                                                           1	
  update
                    seman3c           1	
  delete	
  +	
  N	
  inserts 1	
  delete	
  +	
  N	
  inserts


                      set	
                    1	
  insert                       1	
  delete               1	
  update
                    seman3c

                      list	
               1	
  insert	
  +	
  M	
           1	
  delete	
  +	
  M	
  
                                                                                                           1	
  update
                    seman3c                     updates                          updates*


                @OneToMany	
  (no	
  cascade	
  op3on)
                                                                                                                         46

Tuesday, November 22, 2011
OneToMany Mapping

                                            add	
                           remove	
                      update	
  
                                          element                           element                       element
                                             Oops, we have a problem.
                      bag	
         (list: removal of nth element, n < size-2)
                                             re-­‐create:     re-­‐create:
                    seman3c           1	
  delete	
  +	
  N	
  inserts 1	
  delete	
  +	
  N	
  inserts
                                                                                                           1	
  update



                      set	
                    1	
  insert                       1	
  delete               1	
  update
                    seman3c

                      list	
               1	
  insert	
  +	
  M	
           1	
  delete	
  +	
  M	
  
                                                                                                           1	
  update
                    seman3c                     updates                          updates*


                @OneToMany	
  (no	
  cascade	
  op3on)
                                                                                                                         47

Tuesday, November 22, 2011
Anti-Pattern #4
                             Inadequate Collection Type (Owning Side)




Tuesday, November 22, 2011
Inadequate Collection Mapping (Owning Side)



   • Description
         –Chosen an inadequate collection mapping on the
          owning side
   • Consequences
         –Additional queries executed
   • Solution
         –Consider your use cases and usage patterns and
          choose a mapping with the least performance overhead

                                                            49

Tuesday, November 22, 2011
Plant a Tree

   @Entity
   public class Forest {
      @Id @GeneratedValue
      private Long id;
      @OneToMany
      Set<Tree> trees = new HashSet<Tree>();

         public void plantTree(Tree tree) {
            trees.add(tree);
         }
   }

   // creates and persists a forest with 10.000 trees

   // new EntityManager and new transaction
   Tree oak = new Tree(“oak”);
   em.persist(oak);
   Forest forest = em.find(Forest.class, id);
   forest.plantTree(oak);




                                                        50

Tuesday, November 22, 2011
Anti-Pattern #5
                                OneToMany as Owning Side




Tuesday, November 22, 2011
OneToMany as Owning Side
   • Description
         –OneToMany used as the owning side of a relationship
   • Consequences
         –Collection elements loaded into memory
         –Possibly unnecessary queries
         –Transaction and locking schema problems: version,
          optimistic locking
   • Solution
         –Use ManyToOne as the owning side and OneToMany
          as the inverse side
         –Or at least exclude the collection from locking
               • @OptimisticLock(excluded=true)
                                              .                 52

Tuesday, November 22, 2011
Plant a Tree
   @Entity
   public class Forest {
      @Id @GeneratedValue
      private Long id;
      @OneToMany (mappedBy = “forest”)
      Set<Tree> trees = new HashSet<Tree>();

         public void plantTree(Tree tree) {
            trees.add(tree);
         }
   }

   @Entity
   public class Tree {
      @Id @GeneratedValue
      private Long id;
      private String name;
      @ManyToOne
      Forest forest;

         public void setForest(Forest forest) {
            this.forest = forest;
            this.forest.plantTree(this);
         }
   }
                                                  53

Tuesday, November 22, 2011
Plant a Tree
   @Entity
   public class Forest {
      @Id @GeneratedValue
      private Long id;
      @OneToMany (mappedBy = “forest”)
      Set<Tree> trees = new HashSet<Tree>();

         public void plantTree(Tree tree) {
            trees.add(tree);
         }
   }

   @Entity
   public class Tree {
      @Id @GeneratedValue
      private Long id;
      private String name;
      @ManyToOne
      Forest forest;

         public void setForest(Forest forest) {
            this.forest = forest;
            this.forest.plantTree(this);
         }
   }
                                                  54

Tuesday, November 22, 2011
Anti-Pattern #6
                             Inadequate Collection Type (Inverse Side)




Tuesday, November 22, 2011
Inadequate Collection Type (Inverse Side)


   • Description
         –Set used as a collection type on the inverse side of a
          relationship and, to keep the model consistent, the
          owning side updates the inverse side
   • Consequences
         –Due to a set semantic, all elements must be loaded
          when we add a new element
   • Solution
         –Use Collection or List instead

                                                                   56

Tuesday, November 22, 2011
Plant a Tree
   @Entity
   public class Forest {
      @Id @GeneratedValue
      private Long id;
      @OneToMany (mappedBy = “forest”)
      Collection<Tree> trees = new HashSet<Tree>();

         public void plantTree(Tree tree) {
            trees.add(tree);
         }
   }

   @Entity
   public class Tree {
      @Id @GeneratedValue
      private Long id;
      private String name;
      @ManyToOne
      Forest forest;

         public void setForest(Forest forest) {
            this.forest = forest;
            this.forest.plantTree(this);
         }
   }
                                                      57

Tuesday, November 22, 2011
Plant a Tree
   @Entity
   public class Forest {
      @Id @GeneratedValue
      private Long id;
      @OneToMany (mappedBy = “forest”)
      Collection<Tree> trees = new HashSet<Tree>();

         public void plantTree(Tree tree) {
            trees.add(tree);
         }
   }

   @Entity
   public class Tree {
      @Id @GeneratedValue
      private Long id;
      private String name;
      @ManyToOne
      Forest forest;

         // ...
   }
   // creates and persists a forest with 10.000 trees

   // new EntityManager and new transaction
   em.remove(forest);                                   58

Tuesday, November 22, 2011
Plant a Tree
   @Entity
   public class Forest {
      @Id @GeneratedValue
      private Long id;
      @OneToMany (mappedBy = “forest”)
      Collection<Tree> trees = new HashSet<Tree>();

         public void plantTree(Tree tree) {
            trees.add(tree);
         }
   }

   @Entity
   public class Tree {
      @Id @GeneratedValue
      private Long id;
      private String name;
      @ManyToOne
      Forest forest;

         // ...
   }
   // creates and persists a forest with 10.000 trees

   // new EntityManager and new transaction
   em.remove(forest);                                   58

Tuesday, November 22, 2011
Plant a Tree
   @Entity
   public class Forest {
      @Id @GeneratedValue
      private Long id;
      @OneToMany (mappedBy = “forest”)
      Collection<Tree> trees = new HashSet<Tree>();

         // ...
   }

   @Entity
   public class Tree {
      @Id @GeneratedValue
      private Long id;
      private String name;
      @ManyToOne
      Forest forest;

         // ...
   }
   // creates and persists a forest with 10.000 trees

   // new EntityManager and new transaction
   for (Tree tree : forest.getTrees()) {
      tree.setForest(null);
   }
                                                        59
   em.remove(forest);
Tuesday, November 22, 2011
Plant a Tree
   @Entity
   public class Forest {
      @Id @GeneratedValue
      private Long id;
      @OneToMany (mappedBy = “forest”)
      Collection<Tree> trees = new HashSet<Tree>();

         // ...
   }

   @Entity
   public class Tree {
      @Id @GeneratedValue
      private Long id;                                  10.000 UPDATES
      private String name;
      @ManyToOne
                                                           1 DELETE
      Forest forest;

         // ...
   }
   // creates and persists a forest with 10.000 trees

   // new EntityManager and new transaction
   for (Tree tree : forest.getTrees()) {
      tree.setForest(null);
   }
                                                                         59
   em.remove(forest);
Tuesday, November 22, 2011
Anti-Pattern #7
                                  One by One Processing




Tuesday, November 22, 2011
Inadequate Collection Type (Inverse Side)


   • Description
         –Sequential processing of a persistent collection/objects
   • Consequences
         –Each database operation performed separately for
          each element
   • Solution
         –Bulk queries
         –That’s why CaveatEmptor was implemented like this
          (aggregate function on a database level)

                                                                 61

Tuesday, November 22, 2011
Conclusions

   • Big data cause big problems
         –Standard mappings don’t handle large datasets well
         –Smart model, bulk processing, projections
   • RTFM
         –Most of information can be found in the hibernate docs
         –Understand what you read
         –Think about consequences
         –And hopefully you’ll be fine :)
   • Hibernate
         –Smarter policies and data structures
                                                               62

Tuesday, November 22, 2011
Contact




   • email: patrycja@yonita.com
   • twitter: @yonlabs
   • www: http://www.yonita.com




                                  63

Tuesday, November 22, 2011

More Related Content

What's hot

Testing Spring Boot application in post-JUnit 4 world
Testing Spring Boot application in post-JUnit 4 worldTesting Spring Boot application in post-JUnit 4 world
Testing Spring Boot application in post-JUnit 4 world
Yura Nosenko
 
Introduction to Node js
Introduction to Node jsIntroduction to Node js
Introduction to Node js
Akshay Mathur
 
Mongo DB 완벽가이드 - 4장 쿼리하기
Mongo DB 완벽가이드 - 4장 쿼리하기Mongo DB 완벽가이드 - 4장 쿼리하기
Mongo DB 완벽가이드 - 4장 쿼리하기
JangHyuk You
 
Icsm20.ppt
Icsm20.pptIcsm20.ppt
Dependency injection and inversion
Dependency injection and inversionDependency injection and inversion
Dependency injection and inversion
chhabraravish23
 
Rest API
Rest APIRest API
Rest API
Phil Aylesworth
 
Convolutional Neural Networks at scale in Spark MLlib
Convolutional Neural Networks at scale in Spark MLlibConvolutional Neural Networks at scale in Spark MLlib
Convolutional Neural Networks at scale in Spark MLlib
DataWorks Summit
 
Firebase for web (웹개발을 위한 파이어베이스) 2 Authentication
Firebase for web (웹개발을 위한 파이어베이스) 2 AuthenticationFirebase for web (웹개발을 위한 파이어베이스) 2 Authentication
Firebase for web (웹개발을 위한 파이어베이스) 2 Authentication
승빈이네 공작소
 
[11]Android DataBinding : 기초에서 고급까지
[11]Android DataBinding : 기초에서 고급까지[11]Android DataBinding : 기초에서 고급까지
[11]Android DataBinding : 기초에서 고급까지
NAVER Engineering
 
Clean code
Clean code Clean code
Clean code
Achintya Kumar
 
신입 SW 개발자 취업 준비
신입 SW 개발자 취업 준비신입 SW 개발자 취업 준비
신입 SW 개발자 취업 준비
인서 박
 
Sencha ExtJs Learning Part 2 - MVC And MVVM Architecture in ExtJs [ENGLISH]
Sencha ExtJs Learning Part 2 - MVC And MVVM Architecture in ExtJs [ENGLISH]Sencha ExtJs Learning Part 2 - MVC And MVVM Architecture in ExtJs [ENGLISH]
Sencha ExtJs Learning Part 2 - MVC And MVVM Architecture in ExtJs [ENGLISH]
Irfan Maulana
 
Iocp advanced
Iocp advancedIocp advanced
Iocp advanced
Nam Hyeonuk
 
Clean Code na Prática
Clean Code na PráticaClean Code na Prática
Clean Code na Prática
Douglas Siviotti
 
Austin Bingham. Transducers in Python. PyCon Belarus
Austin Bingham. Transducers in Python. PyCon BelarusAustin Bingham. Transducers in Python. PyCon Belarus
Austin Bingham. Transducers in Python. PyCon Belarus
Alina Dolgikh
 
Multi-threaded Programming in JAVA
Multi-threaded Programming in JAVAMulti-threaded Programming in JAVA
Multi-threaded Programming in JAVA
Vikram Kalyani
 
Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js + Expres...
Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js +  Expres...Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js +  Expres...
Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js + Expres...
Edureka!
 
Baekjoon Online Judge 1019번 풀이
Baekjoon Online Judge 1019번 풀이Baekjoon Online Judge 1019번 풀이
Baekjoon Online Judge 1019번 풀이
Baekjoon Choi
 
What is Node.js | Node.js Tutorial for Beginners | Node.js Modules | Node.js ...
What is Node.js | Node.js Tutorial for Beginners | Node.js Modules | Node.js ...What is Node.js | Node.js Tutorial for Beginners | Node.js Modules | Node.js ...
What is Node.js | Node.js Tutorial for Beginners | Node.js Modules | Node.js ...
Edureka!
 
Doctrine Internals. UnitOfWork
Doctrine Internals. UnitOfWorkDoctrine Internals. UnitOfWork
Doctrine Internals. UnitOfWork
Andrew Yatsenko
 

What's hot (20)

Testing Spring Boot application in post-JUnit 4 world
Testing Spring Boot application in post-JUnit 4 worldTesting Spring Boot application in post-JUnit 4 world
Testing Spring Boot application in post-JUnit 4 world
 
Introduction to Node js
Introduction to Node jsIntroduction to Node js
Introduction to Node js
 
Mongo DB 완벽가이드 - 4장 쿼리하기
Mongo DB 완벽가이드 - 4장 쿼리하기Mongo DB 완벽가이드 - 4장 쿼리하기
Mongo DB 완벽가이드 - 4장 쿼리하기
 
Icsm20.ppt
Icsm20.pptIcsm20.ppt
Icsm20.ppt
 
Dependency injection and inversion
Dependency injection and inversionDependency injection and inversion
Dependency injection and inversion
 
Rest API
Rest APIRest API
Rest API
 
Convolutional Neural Networks at scale in Spark MLlib
Convolutional Neural Networks at scale in Spark MLlibConvolutional Neural Networks at scale in Spark MLlib
Convolutional Neural Networks at scale in Spark MLlib
 
Firebase for web (웹개발을 위한 파이어베이스) 2 Authentication
Firebase for web (웹개발을 위한 파이어베이스) 2 AuthenticationFirebase for web (웹개발을 위한 파이어베이스) 2 Authentication
Firebase for web (웹개발을 위한 파이어베이스) 2 Authentication
 
[11]Android DataBinding : 기초에서 고급까지
[11]Android DataBinding : 기초에서 고급까지[11]Android DataBinding : 기초에서 고급까지
[11]Android DataBinding : 기초에서 고급까지
 
Clean code
Clean code Clean code
Clean code
 
신입 SW 개발자 취업 준비
신입 SW 개발자 취업 준비신입 SW 개발자 취업 준비
신입 SW 개발자 취업 준비
 
Sencha ExtJs Learning Part 2 - MVC And MVVM Architecture in ExtJs [ENGLISH]
Sencha ExtJs Learning Part 2 - MVC And MVVM Architecture in ExtJs [ENGLISH]Sencha ExtJs Learning Part 2 - MVC And MVVM Architecture in ExtJs [ENGLISH]
Sencha ExtJs Learning Part 2 - MVC And MVVM Architecture in ExtJs [ENGLISH]
 
Iocp advanced
Iocp advancedIocp advanced
Iocp advanced
 
Clean Code na Prática
Clean Code na PráticaClean Code na Prática
Clean Code na Prática
 
Austin Bingham. Transducers in Python. PyCon Belarus
Austin Bingham. Transducers in Python. PyCon BelarusAustin Bingham. Transducers in Python. PyCon Belarus
Austin Bingham. Transducers in Python. PyCon Belarus
 
Multi-threaded Programming in JAVA
Multi-threaded Programming in JAVAMulti-threaded Programming in JAVA
Multi-threaded Programming in JAVA
 
Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js + Expres...
Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js +  Expres...Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js +  Expres...
Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js + Expres...
 
Baekjoon Online Judge 1019번 풀이
Baekjoon Online Judge 1019번 풀이Baekjoon Online Judge 1019번 풀이
Baekjoon Online Judge 1019번 풀이
 
What is Node.js | Node.js Tutorial for Beginners | Node.js Modules | Node.js ...
What is Node.js | Node.js Tutorial for Beginners | Node.js Modules | Node.js ...What is Node.js | Node.js Tutorial for Beginners | Node.js Modules | Node.js ...
What is Node.js | Node.js Tutorial for Beginners | Node.js Modules | Node.js ...
 
Doctrine Internals. UnitOfWork
Doctrine Internals. UnitOfWorkDoctrine Internals. UnitOfWork
Doctrine Internals. UnitOfWork
 

More from Codemotion

Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Codemotion
 
Pompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyPompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending story
Codemotion
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storia
Codemotion
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard Altwasser
Codemotion
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Codemotion
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Codemotion
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Codemotion
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 - Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Codemotion
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Codemotion
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Codemotion
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Codemotion
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Codemotion
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Codemotion
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Codemotion
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Codemotion
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
Codemotion
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Codemotion
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Codemotion
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Codemotion
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Codemotion
 

More from Codemotion (20)

Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
 
Pompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyPompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending story
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storia
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard Altwasser
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 - Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
 

Recently uploaded

Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
sunilverma7884
 
UX Webinar Series: Aligning Authentication Experiences with Business Goals
UX Webinar Series: Aligning Authentication Experiences with Business GoalsUX Webinar Series: Aligning Authentication Experiences with Business Goals
UX Webinar Series: Aligning Authentication Experiences with Business Goals
FIDO Alliance
 
leewayhertz.com-Generative AI tech stack Frameworks infrastructure models and...
leewayhertz.com-Generative AI tech stack Frameworks infrastructure models and...leewayhertz.com-Generative AI tech stack Frameworks infrastructure models and...
leewayhertz.com-Generative AI tech stack Frameworks infrastructure models and...
alexjohnson7307
 
Vulnerability Management: A Comprehensive Overview
Vulnerability Management: A Comprehensive OverviewVulnerability Management: A Comprehensive Overview
Vulnerability Management: A Comprehensive Overview
Steven Carlson
 
Keynote : AI & Future Of Offensive Security
Keynote : AI & Future Of Offensive SecurityKeynote : AI & Future Of Offensive Security
Keynote : AI & Future Of Offensive Security
Priyanka Aash
 
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and DisadvantagesBLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
SAI KAILASH R
 
Camunda Chapter NY Meetup July 2024.pptx
Camunda Chapter NY Meetup July 2024.pptxCamunda Chapter NY Meetup July 2024.pptx
Camunda Chapter NY Meetup July 2024.pptx
ZachWylie3
 
Mastering Board Best Practices: Essential Skills for Effective Non-profit Lea...
Mastering Board Best Practices: Essential Skills for Effective Non-profit Lea...Mastering Board Best Practices: Essential Skills for Effective Non-profit Lea...
Mastering Board Best Practices: Essential Skills for Effective Non-profit Lea...
OnBoard
 
The Path to General-Purpose Robots - Coatue
The Path to General-Purpose Robots - CoatueThe Path to General-Purpose Robots - Coatue
The Path to General-Purpose Robots - Coatue
Razin Mustafiz
 
Intel Unveils Core Ultra 200V Lunar chip .pdf
Intel Unveils Core Ultra 200V Lunar chip .pdfIntel Unveils Core Ultra 200V Lunar chip .pdf
Intel Unveils Core Ultra 200V Lunar chip .pdf
Tech Guru
 
Retrieval Augmented Generation Evaluation with Ragas
Retrieval Augmented Generation Evaluation with RagasRetrieval Augmented Generation Evaluation with Ragas
Retrieval Augmented Generation Evaluation with Ragas
Zilliz
 
Improving Learning Content Efficiency with Reusable Learning Content
Improving Learning Content Efficiency with Reusable Learning ContentImproving Learning Content Efficiency with Reusable Learning Content
Improving Learning Content Efficiency with Reusable Learning Content
Enterprise Knowledge
 
leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
leewayhertz.com-AI agents for healthcare Applications benefits and implementa...leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
alexjohnson7307
 
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
Zilliz
 
Uncharted Together- Navigating AI's New Frontiers in Libraries
Uncharted Together- Navigating AI's New Frontiers in LibrariesUncharted Together- Navigating AI's New Frontiers in Libraries
Uncharted Together- Navigating AI's New Frontiers in Libraries
Brian Pichman
 
Communications Mining Series - Zero to Hero - Session 3
Communications Mining Series - Zero to Hero - Session 3Communications Mining Series - Zero to Hero - Session 3
Communications Mining Series - Zero to Hero - Session 3
DianaGray10
 
Sonkoloniya documentation - ONEprojukti.pdf
Sonkoloniya documentation - ONEprojukti.pdfSonkoloniya documentation - ONEprojukti.pdf
Sonkoloniya documentation - ONEprojukti.pdf
SubhamMandal40
 
NVIDIA at Breakthrough Discuss for Space Exploration
NVIDIA at Breakthrough Discuss for Space ExplorationNVIDIA at Breakthrough Discuss for Space Exploration
NVIDIA at Breakthrough Discuss for Space Exploration
Alison B. Lowndes
 
EuroPython 2024 - Streamlining Testing in a Large Python Codebase
EuroPython 2024 - Streamlining Testing in a Large Python CodebaseEuroPython 2024 - Streamlining Testing in a Large Python Codebase
EuroPython 2024 - Streamlining Testing in a Large Python Codebase
Jimmy Lai
 
Premium Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Service ...
Premium Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Service ...Premium Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Service ...
Premium Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Service ...
shanihomely
 

Recently uploaded (20)

Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
Girls call Kolkata 👀 XXXXXXXXXXX 👀 Rs.9.5 K Cash Payment With Room Delivery
 
UX Webinar Series: Aligning Authentication Experiences with Business Goals
UX Webinar Series: Aligning Authentication Experiences with Business GoalsUX Webinar Series: Aligning Authentication Experiences with Business Goals
UX Webinar Series: Aligning Authentication Experiences with Business Goals
 
leewayhertz.com-Generative AI tech stack Frameworks infrastructure models and...
leewayhertz.com-Generative AI tech stack Frameworks infrastructure models and...leewayhertz.com-Generative AI tech stack Frameworks infrastructure models and...
leewayhertz.com-Generative AI tech stack Frameworks infrastructure models and...
 
Vulnerability Management: A Comprehensive Overview
Vulnerability Management: A Comprehensive OverviewVulnerability Management: A Comprehensive Overview
Vulnerability Management: A Comprehensive Overview
 
Keynote : AI & Future Of Offensive Security
Keynote : AI & Future Of Offensive SecurityKeynote : AI & Future Of Offensive Security
Keynote : AI & Future Of Offensive Security
 
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and DisadvantagesBLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
BLOCKCHAIN TECHNOLOGY - Advantages and Disadvantages
 
Camunda Chapter NY Meetup July 2024.pptx
Camunda Chapter NY Meetup July 2024.pptxCamunda Chapter NY Meetup July 2024.pptx
Camunda Chapter NY Meetup July 2024.pptx
 
Mastering Board Best Practices: Essential Skills for Effective Non-profit Lea...
Mastering Board Best Practices: Essential Skills for Effective Non-profit Lea...Mastering Board Best Practices: Essential Skills for Effective Non-profit Lea...
Mastering Board Best Practices: Essential Skills for Effective Non-profit Lea...
 
The Path to General-Purpose Robots - Coatue
The Path to General-Purpose Robots - CoatueThe Path to General-Purpose Robots - Coatue
The Path to General-Purpose Robots - Coatue
 
Intel Unveils Core Ultra 200V Lunar chip .pdf
Intel Unveils Core Ultra 200V Lunar chip .pdfIntel Unveils Core Ultra 200V Lunar chip .pdf
Intel Unveils Core Ultra 200V Lunar chip .pdf
 
Retrieval Augmented Generation Evaluation with Ragas
Retrieval Augmented Generation Evaluation with RagasRetrieval Augmented Generation Evaluation with Ragas
Retrieval Augmented Generation Evaluation with Ragas
 
Improving Learning Content Efficiency with Reusable Learning Content
Improving Learning Content Efficiency with Reusable Learning ContentImproving Learning Content Efficiency with Reusable Learning Content
Improving Learning Content Efficiency with Reusable Learning Content
 
leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
leewayhertz.com-AI agents for healthcare Applications benefits and implementa...leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
 
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
Garbage In, Garbage Out: Why poor data curation is killing your AI models (an...
 
Uncharted Together- Navigating AI's New Frontiers in Libraries
Uncharted Together- Navigating AI's New Frontiers in LibrariesUncharted Together- Navigating AI's New Frontiers in Libraries
Uncharted Together- Navigating AI's New Frontiers in Libraries
 
Communications Mining Series - Zero to Hero - Session 3
Communications Mining Series - Zero to Hero - Session 3Communications Mining Series - Zero to Hero - Session 3
Communications Mining Series - Zero to Hero - Session 3
 
Sonkoloniya documentation - ONEprojukti.pdf
Sonkoloniya documentation - ONEprojukti.pdfSonkoloniya documentation - ONEprojukti.pdf
Sonkoloniya documentation - ONEprojukti.pdf
 
NVIDIA at Breakthrough Discuss for Space Exploration
NVIDIA at Breakthrough Discuss for Space ExplorationNVIDIA at Breakthrough Discuss for Space Exploration
NVIDIA at Breakthrough Discuss for Space Exploration
 
EuroPython 2024 - Streamlining Testing in a Large Python Codebase
EuroPython 2024 - Streamlining Testing in a Large Python CodebaseEuroPython 2024 - Streamlining Testing in a Large Python Codebase
EuroPython 2024 - Streamlining Testing in a Large Python Codebase
 
Premium Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Service ...
Premium Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Service ...Premium Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Service ...
Premium Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Service ...
 

Performance Anti-Patterns in Hibernatee, by Patrycja Wegrzynowicz

  • 1. Performance Anti-Patterns in Hibernate Patrycja Wegrzynowicz CTO Yonita, Inc. Tuesday, November 22, 2011
  • 2. About Me • 10+ years of professional experience • PhD in Computer Science –Patterns and anti-patterns, static and dynamic code analysis, language semantics, compiler design • Active author and speaker –JavaOne, Devoxx, JavaZone, Jazoon, OOPSLA, ASE... • CTO of Yonita, Inc. –Bridge the gap between the industry and the academia –Automated defects detection and optimization –Performance, security, concurrency, databases • Twitter @yonlabs 2 Tuesday, November 22, 2011
  • 3. Agenda • 4 puzzles –Short program with curious behavior –Question to you (multiple choice) –Mystery revealed –Lessons learned • 7 performance anti-patterns –Description, consequences, solutions 3 Tuesday, November 22, 2011
  • 4. Disclaimer I do think Hibernate is a great tool! 4 Tuesday, November 22, 2011
  • 8. Puzzle #1 Less Is More Tuesday, November 22, 2011
  • 9. Who knows CaveatEmptor app? 7 Tuesday, November 22, 2011
  • 10. Who’s read Java Persistence with Hibernate? 8 Tuesday, November 22, 2011
  • 11. CaveatEmptor • Demo application from ‘Java Persistence with Hibernate’ • Simple auction system 9 Tuesday, November 22, 2011
  • 12. I’m Gonna Win This Auction! public class PlaceBidAction implements Action { // invoked in a new transaction public String execute(Map even) { // ... Bid currentMinBid = itemDAO.getMinBid(itemId); Bid currentMaxBid = itemDAO.getMaxBid(itemId); // uses load with Lock.UPGRADE Item item = itemDAO.findById(itemId, true); Bid newBid = item.placeBid(userDAO.findById(userId, false), newAmount, currentMaxBid, currentMinBid); // ... } } 10 Tuesday, November 22, 2011
  • 13. What’s the Problem? (a) None (code is correct) (b) Transaction/lock mgmt public class PlaceBidAction implements Action { (c) Exception thrown // invoked in a new transaction (d) None of the above public String execute(Map even) { // ... Bid currentMinBid = itemDAO.getMinBid(itemId); Bid currentMaxBid = itemDAO.getMaxBid(itemId); // uses load with Lock.UPGRADE Item item = itemDAO.findById(itemId, true); Bid newBid = item.placeBid(userDAO.findById(userId, false), newAmount, currentMaxBid, currentMinBid); // ... } } 11 Tuesday, November 22, 2011
  • 14. What’s the Problem? (a) None (the code is correct) (b) Transaction/Lock management (c) Exception thrown (d) None of the above The bids can change between calling getMaxBid and locking the item. 12 Tuesday, November 22, 2011
  • 15. Another Look public class PlaceBidAction implements Action { // invoked in a new transaction public String execute(Map even) { // ... Bid currentMinBid = itemDAO.getMinBid(itemId); Bid currentMaxBid = itemDAO.getMaxBid(itemId); // here, the bids can be modified by a different transaction // uses load with Lock.UPGRADE Item item = itemDAO.findById(itemId, true); Bid newBid = item.placeBid(userDAO.findById(userId, false), newAmount, currentMaxBid, currentMinBid); // ... } } 13 Tuesday, November 22, 2011
  • 16. 2 Users and Item with 2 Bids Thread A (new amount 100) Thread B (new amount 30) (1) // begin transaction // item with 2 bids: 10,20 Bid curMax = dao.getMaxBid(id); // curMax = 20 14 Tuesday, November 22, 2011
  • 17. 2 Users and Item with 2 Bids Thread A (new amount 100) Thread B (new amount 30) (1) (2) // begin transaction // begin transaction // item with 2 bids: 10,20 // item with 2 bids: 10,20 Bid curMax = dao.getMaxBid(id); Bid curMax = dao.getMaxBid(id); // curMax = 20 // curMax = 20 15 Tuesday, November 22, 2011
  • 18. 2 Users and Item with 2 Bids Thread A (new amount 100) Thread B (new amount 30) (1) (2) // begin transaction // begin transaction // item with 2 bids: 10,20 // item with 2 bids: 10,20 Bid curMax = dao.getMaxBid(id); Bid curMax = dao.getMaxBid(id); // curMax = 20 // curMax = 20 (3) // item with 2 bids: 10,20 // Lock.UPGRADE Item item = dao.findById(id,true); Bid newBid = item.placeBid(..., newAmount, curMax, ...); // commit transaction // item with 3 bids: 10,20,100 Successful bid: 100 16 Tuesday, November 22, 2011
  • 19. 2 Users and Item with 2 Bids Thread A (new amount 100) Thread B (new amount 30) (1) (2) // begin transaction // begin transaction // item with 2 bids: 10,20 // item with 2 bids: 10,20 Bid curMax = dao.getMaxBid(id); Bid curMax = dao.getMaxBid(id); // curMax = 20 // curMax = 20 (3) (4) // item with 2 bids: 10,20 // item with 3 bids: 10,20,100 // Lock.UPGRADE // Lock.UPGRADE Item item = dao.findById(id,true); Item item = dao.findById(id,true); Bid newBid = item.placeBid(..., Bid newBid = item.placeBid(..., newAmount, newAmount, curMax, ...); curMax, ...); // commit transaction // commit transaction // item with 3 bids: 10,20,100 // item with 4 bids: 10,20,100,30 Successful bid: 100 Successful bid: 30 17 Tuesday, November 22, 2011
  • 20. How To Fix It? public class PlaceBidAction implements Action { // invoked in a new transaction public String execute(Map even) { // ... Bid currentMinBid = itemDAO.getMinBid(itemId); Bid currentMaxBid = itemDAO.getMaxBid(itemId); // uses load with Lock.UPGRADE Item item = itemDAO.findById(itemId, true); Bid newBid = item.placeBid(userDAO.findById(userId, false), newAmount, currentMaxBid, currentMinBid); // ... } } 18 Tuesday, November 22, 2011
  • 21. How To Fix It? version and optimistic locking public class PlaceBidAction implements Action { // invoked in a new transaction public String execute(Map even) { // ... Bid currentMinBid = itemDAO.getMinBid(itemId); Bid currentMaxBid = itemDAO.getMaxBid(itemId); // uses load with Lock.UPGRADE Item item = itemDAO.findById(itemId, true); Bid newBid = item.placeBid(userDAO.findById(userId, false), newAmount, currentMaxBid, currentMinBid); // ... } } 18 Tuesday, November 22, 2011
  • 22. How To Fix It? version and NO optimistic locking public class PlaceBidAction implements Action { // invoked in a new transaction public String execute(Map even) { // ... Bid currentMinBid = itemDAO.getMinBid(itemId); Bid currentMaxBid = itemDAO.getMaxBid(itemId); // uses load with Lock.UPGRADE Item item = itemDAO.findById(itemId, true); Bid newBid = item.placeBid(userDAO.findById(userId, false), newAmount, currentMaxBid, currentMinBid); // ... } } 18 Tuesday, November 22, 2011
  • 23. How To Fix It? version and NO optimistic locking REPEATABLE public class PlaceBidAction implements Action { // invoked in a new transaction READS public String execute(Map even) { // ... Bid currentMinBid = itemDAO.getMinBid(itemId); Bid currentMaxBid = itemDAO.getMaxBid(itemId); // uses load with Lock.UPGRADE Item item = itemDAO.findById(itemId, true); Bid newBid = item.placeBid(userDAO.findById(userId, false), newAmount, currentMaxBid, currentMinBid); // ... } } 18 Tuesday, November 22, 2011
  • 24. How To Fix It? version and NO optimistic locking REPEATABLE public class PlaceBidAction implements Action { // invoked in a new transaction READS public String execute(Map even) { // ... SERIALIZABLE Bid currentMinBid = itemDAO.getMinBid(itemId); Bid currentMaxBid = itemDAO.getMaxBid(itemId); // uses load with Lock.UPGRADE Item item = itemDAO.findById(itemId, true); Bid newBid = item.placeBid(userDAO.findById(userId, false), newAmount, currentMaxBid, currentMinBid); // ... } } 18 Tuesday, November 22, 2011
  • 25. How To Fix It? version and NO optimistic locking REPEATABLE public class PlaceBidAction implements Action { NO // invoked in a new transaction READS public String execute(Map even) { // ... SERIALIZABLE Bid currentMinBid = itemDAO.getMinBid(itemId); Bid currentMaxBid = itemDAO.getMaxBid(itemId); // uses load with Lock.UPGRADE Item item = itemDAO.findById(itemId, true); Bid newBid = item.placeBid(userDAO.findById(userId, false), newAmount, currentMaxBid, currentMinBid); // ... } } 18 Tuesday, November 22, 2011
  • 26. How To Fix It? version and NO optimistic locking REPEATABLE public class PlaceBidAction implements Action { NO // invoked in a new transaction READS public String execute(Map even) { // ... SERIALIZABLE YES Bid currentMinBid = itemDAO.getMinBid(itemId); Bid currentMaxBid = itemDAO.getMaxBid(itemId); // uses load with Lock.UPGRADE Item item = itemDAO.findById(itemId, true); Bid newBid = item.placeBid(userDAO.findById(userId, false), newAmount, currentMaxBid, currentMinBid); // ... } } 18 Tuesday, November 22, 2011
  • 27. How To Fix It? version and NO optimistic locking REPEATABLE public class PlaceBidAction implements Action { NO // invoked in a new transaction READS public String execute(Map even) { // ... SERIALIZABLE YES Bid currentMinBid = itemDAO.getMinBid(itemId); Bid currentMaxBid = itemDAO.getMaxBid(itemId); move lock before // uses load with Lock.UPGRADE getMinBid/ Item item = itemDAO.findById(itemId, true); getMaxBid Bid newBid = item.placeBid(userDAO.findById(userId, false), newAmount, currentMaxBid, currentMinBid); // ... } } 18 Tuesday, November 22, 2011
  • 28. How To Fix It? version and NO optimistic locking REPEATABLE public class PlaceBidAction implements Action { NO // invoked in a new transaction READS public String execute(Map even) { // ... SERIALIZABLE YES Bid currentMinBid = itemDAO.getMinBid(itemId); Bid currentMaxBid = itemDAO.getMaxBid(itemId); move lock before // uses load with Lock.UPGRADE getMinBid/ YES Item item = itemDAO.findById(itemId, true); getMaxBid Bid newBid = item.placeBid(userDAO.findById(userId, false), newAmount, currentMaxBid, currentMinBid); // ... } } 18 Tuesday, November 22, 2011
  • 29. How To Fix It? version and NO optimistic locking REPEATABLE public class PlaceBidAction implements Action { NO // invoked in a new transaction READS public String execute(Map even) { // ... SERIALIZABLE YES Bid currentMinBid = itemDAO.getMinBid(itemId); Bid currentMaxBid = itemDAO.getMaxBid(itemId); move lock before // uses load with Lock.UPGRADE getMinBid/ YES Item item = itemDAO.findById(itemId, true); getMaxBid Bid newBid = item.placeBid(userDAO.findById(userId, false), newAmount, currentMaxBid, different currentMinBid); object model // ... } } 18 Tuesday, November 22, 2011
  • 30. How To Fix It? version and NO optimistic locking REPEATABLE public class PlaceBidAction implements Action { NO // invoked in a new transaction READS public String execute(Map even) { // ... SERIALIZABLE YES Bid currentMinBid = itemDAO.getMinBid(itemId); Bid currentMaxBid = itemDAO.getMaxBid(itemId); move lock before // uses load with Lock.UPGRADE getMinBid/ YES Item item = itemDAO.findById(itemId, true); getMaxBid Bid newBid = item.placeBid(userDAO.findById(userId, false), newAmount, currentMaxBid, different YES currentMinBid); object model // ... } } 18 Tuesday, November 22, 2011
  • 31. How To Fix It? version and NO optimistic locking REPEATABLE public class PlaceBidAction implements Action { NO // invoked in a new transaction READS public String execute(Map even) { // ... SERIALIZABLE YES Bid currentMinBid = itemDAO.getMinBid(itemId); Bid currentMaxBid = itemDAO.getMaxBid(itemId); move lock before // uses load with Lock.UPGRADE getMinBid/ YES Item item = itemDAO.findById(itemId, true); getMaxBid Bid newBid = item.placeBid(userDAO.findById(userId, false), newAmount, currentMaxBid, different YES currentMinBid); object model // ... } } Java synchronized 18 Tuesday, November 22, 2011
  • 32. How To Fix It? version and NO optimistic locking REPEATABLE public class PlaceBidAction implements Action { NO // invoked in a new transaction READS public String execute(Map even) { // ... SERIALIZABLE YES Bid currentMinBid = itemDAO.getMinBid(itemId); Bid currentMaxBid = itemDAO.getMaxBid(itemId); move lock before // uses load with Lock.UPGRADE getMinBid/ YES Item item = itemDAO.findById(itemId, true); getMaxBid Bid newBid = item.placeBid(userDAO.findById(userId, false), newAmount, currentMaxBid, different YES currentMinBid); object model // ... } Java } YES synchronized 18 Tuesday, November 22, 2011
  • 33. Lessons Learned • Nobody’s perfect ;-) • ACID is only a theory –Simple transaction interceptor/annotation often is not enough –Query order does matter –Learn more about locks and transaction isolation levels • Premature optimization is the root of all evil –Performance Anti-Pattern #1 19 Tuesday, November 22, 2011
  • 34. Performance Lessons • Object model • Usage patterns –Concurrent users –Data volume • Transaction and locking management 20 Tuesday, November 22, 2011
  • 35. Puzzle #2 Heads of Hydra Tuesday, November 22, 2011
  • 36. Heads of Hydra @Entity public class Hydra { private Long id; private List<Head> heads = new ArrayList<Head>(); @Id @GeneratedValue public Long getId() {...} protected void setId() {...} @OneToMany(cascade=CascadeType.ALL) public List<Head> getHeads() { return Collections.unmodifiableList(heads); } protected void setHeads(List<Head> heads) {...} } // creates and persists the hydra with 3 heads // new EntityManager and new transaction Hydra found = em.find(Hydra.class, hydra.getId()); 22 Tuesday, November 22, 2011
  • 37. How Many Queries in 2nd Tx? (a) 1 select (b) 2 selects @Entity (c) 1+3 selects public class Hydra { private Long id; (d) 2 selects, 1 delete, 3 private List<Head> heads = new ArrayList<Head>(); inserts (e) None of the above @Id @GeneratedValue public Long getId() {...} protected void setId() {...} @OneToMany(cascade=CascadeType.ALL) public List<Head> getHeads() { return Collections.unmodifiableList(heads); } protected void setHeads(List<Head> heads) {...} } // creates and persists the hydra with 3 heads // new EntityManager and new transaction Hydra found = em.find(Hydra.class, hydra.getId()); 23 Tuesday, November 22, 2011
  • 38. How Many Queries in 2nd Tx? (a) 1 select (b) 2 selects (c) 1+3 selects (d) 2 selects, 1 delete, 3 inserts (e) None of the above During commit hibernate checks whether the collection property is dirty (needs to be re- created) by comparing Java identities (object references). 24 Tuesday, November 22, 2011
  • 39. Another Look @Entity public class Hydra { private Long id; private List<Head> heads = new ArrayList<Head>(); @Id @GeneratedValue public Long getId() {...} protected void setId() {...} @OneToMany(cascade=CascadeType.ALL) public List<Head> getHeads() { return Collections.unmodifiableList(heads); } protected void setHeads(List<Head> heads) {...} } // creates and persists hydra with three heads // new EntityManager and new transaction // during find only 1 select (hydra) Hydra found = em.find(Hydra.class, hydra.getId()); // during commit 1 select (heads),1 delete (heads),3 inserts (heads) 25 Tuesday, November 22, 2011
  • 40. How To Fix It? @Entity public class Hydra { @Id @GeneratedValue private Long id; @OneToMany(cascade=CascadeType.ALL) private List<Head> heads = new ArrayList<Head>(); public Long getId() {...} protected void setId() {...} public List<Head> getHeads() { return Collections.unmodifiableList(heads); } protected void setHeads(List<Head> heads) {...} } // creates and persists hydra with three heads // new EntityManager and new transaction Hydra found = em.find(Hydra.class, hydra.getId()); 26 Tuesday, November 22, 2011
  • 41. Lessons Learned • Expect unexpected ;-) • Prefer field access mappings • And... 27 Tuesday, November 22, 2011
  • 42. Anti-Pattern #2 Lost Collection Proxy on Owning Side Tuesday, November 22, 2011
  • 43. Lost Collection Proxy • Description –On the owning side of an association, we assign a new collection object to a persistent field/property overriding a collection proxy returned by hibernate • Consequences –The entire collection is re-created: one delete to remove all elements and then many element inserts 29 Tuesday, November 22, 2011
  • 44. Lost Collection Proxy - Example @Entity public class Hydra { @Id @GeneratedValue private Long id; @OneToMany(cascade=CascadeType.ALL) private List<Head> heads = new ArrayList<Head>(); public Long getId() {...} protected void setId() {...} public List<Head> getHeads() { return heads; } public void setHeads(List<Head> heads) { this.heads = heads; } } 30 Tuesday, November 22, 2011
  • 45. Lost Collection Proxy - Solution • Operate on collection objects returned by hibernate –In most cases it’s a much more efficient solution • Unless you know what you’re doing –It might be performance-wise in some cases to re- create the entire collection (bulk delete) –However, it’s the place when hibernate could do better, having all required data available: • Original size, added and removed elements • Min(#added + #removed, 1 + #size - #removed + #added) 31 Tuesday, November 22, 2011
  • 46. Puzzle #3 Fashionable Developer Tuesday, November 22, 2011
  • 47. Fashionable Developer @Entity public class Developer { @Id @GeneratedValue private Long id; private String mainTechnology; public boolean likesMainTechnology() { return "hibernate".equalsIgnoreCase(mainTechnology); } } // creates and persists a developer that uses hibernate as mainTechnology // new EntityManager and new transaction Developer dev = em.find(Developer.class, id); boolean foundCoolStuff = false; for (String tech : new String[]{"HTML5", "Android", "Scala"}) { dev.setMainTechnology(tech); // othersAreUsingIt: // select count(*) from Developer where mainTechnology = ? and id != ? if (othersAreUsingIt(tech, dev) && dev.likesMainTechnology()) { foundCoolStuff = true; break; } } if (!foundCoolStuff) { // still use hibernate dev.setMainTechnology("hibernate"); 33 } Tuesday, November 22, 2011
  • 48. How Many Queries in 2nd Tx? @Entity public class Developer { (a) 2 select @Id @GeneratedValue (b) 4 selects private Long id; private String mainTechnology; (c) 4 selects, 1 update (d) 4 selects, 4 updates public boolean likesMainTechnology() { (e) None of the above return "hibernate".equalsIgnoreCase(mainTechnology); } } // creates and persists a developer that uses hibernate as mainTechnology // new EntityManager and new transaction Developer dev = em.find(Developer.class, id); boolean foundCoolStuff = false; for (String tech : new String[]{"HTML5", "Android", "Scala"}) { dev.setMainTechnology(tech); // othersAreUsingIt: // select count(*) from Developer where mainTechnology = ? and id != ? if (othersAreUsingIt(tech, dev) && dev.likesMainTechnology()) { foundCoolStuff = true; break; } } if (!foundCoolStuff) { // still use hibernate dev.setMainTechnology("hibernate"); 34 } Tuesday, November 22, 2011
  • 49. How Many Queries in 2nd Tx? (a) 2 selects (b) 4 selects (c) 4 selects, 1 update (d) 4 selects, 4 inserts (e) None of the above Hibernate must guarantee correctness of executed queries, therefore in certain situations it must perform flushes during a transaction. 35 Tuesday, November 22, 2011
  • 50. Fashionable Developer @Entity public class Developer { @Id @GeneratedValue private Long id; private String mainTechnology; NO UPDATES public boolean likesMainTechnology() { return "hibernate".equalsIgnoreCase(mainTechnology); } } // creates and persists a developer that uses hibernate as mainTechnology // new EntityManager and new transaction Developer dev = em.find(Developer.class, id); boolean foundCoolStuff = false; for (String tech : new String[]{"HTML5", "Android", "Scala"}) { dev.setMainTechnology(tech); // othersAreUsingIt: // select count(*) from Developer where mainTechnology = ? and id != ? if (/*othersAreUsingIt(tech, dev) &&*/ dev.likesMainTechnology()) { foundCoolStuff = true; break; } } if (!foundCoolStuff) { // still use hibernate dev.setMainTechnology("hibernate"); 36 } Tuesday, November 22, 2011
  • 51. Anti-Pattern #3 Temporary Changes Tuesday, November 22, 2011
  • 52. Temporary Changes • Description –We change the persistent data of an object temporarily to test some features –In the meantime a database flush occurs triggered, for example, by a HQL touching the table • Consequences –Flushes can be performed during the transaction, not only at the commit time –Temporary changes persisted into the database unnecessarily • Solution –Plan your business model and processing to avoid temporary changes to your persistent data 38 Tuesday, November 22, 2011
  • 53. Puzzle #4 Plant a Tree Tuesday, November 22, 2011
  • 54. Plant a Tree @Entity public class Forest { @Id @GeneratedValue private Long id; @OneToMany Collection<Tree> trees = new HashSet<Tree>(); public void plantTree(Tree tree) { trees.add(tree); } } // creates and persists a forest with 10.000 trees // new EntityManager and new transaction Tree tree = new Tree(“oak”); em.persist(tree); Forest forest = em.find(Forest.class, id); forest.plantTree(tree); 40 Tuesday, November 22, 2011
  • 55. How Many Queries in 2nd Tx? @Entity (a) 1 select, 2 inserts public class Forest { (b) 2 selects, 2 inserts @Id @GeneratedValue (c) 2 selects, 1 delete, private Long id; @OneToMany 10.000+2 inserts Collection<Tree> trees = new HashSet<Tree>(); (d) Even more ;-) public void plantTree(Tree tree) { trees.add(tree); } } // creates and persists a forest with 10.000 trees // new EntityManager and new transaction Tree tree = new Tree(“oak”); em.persist(tree); Forest forest = em.find(Forest.class, id); forest.plantTree(tree); 41 Tuesday, November 22, 2011
  • 56. How Many Queries in 2nd Tx? (a) 1 select, 2 inserts (b) 2 selects, 2 inserts (c) 2 selects, 1 delete, 10.000+2 inserts (d) Even more ;-) The combination of OneToMany and Collection enables a bag semantic. That’s why the collection is re-created. 42 Tuesday, November 22, 2011
  • 57. Plant a Tree - Revisited @Entity public class Orchard { @Id @GeneratedValue private Long id; @OneToMany List<Tree> trees = new ArrayList<Tree>(); public void plantTree(Tree tree) { trees.add(tree); } } // creates and persists a forest with 10.000 trees // new EntityManager and new transaction Tree tree = new Tree(“apple tree”); em.persist(tree); Orchard orchard = em.find(Orchard.class, id); orchard.plantTree(tree); 43 Tuesday, November 22, 2011
  • 58. Plant a Tree - Revisited @Entity public class Orchard { STILL BAG SEMANTIC! @Id @GeneratedValue private Long id; @OneToMany List<Tree> trees = new ArrayList<Tree>(); public void plantTree(Tree tree) { trees.add(tree); } } // creates and persists a forest with 10.000 trees // new EntityManager and new transaction Tree tree = new Tree(“apple tree”); em.persist(tree); Orchard orchard = em.find(Orchard.class, id); orchard.plantTree(tree); 43 Tuesday, November 22, 2011
  • 59. Plant a Tree - Revisited @Entity public class Orchard { STILL BAG SEMANTIC! @Id @GeneratedValue private Long id; Use OrderColumn or @OneToMany List<Tree> trees = new ArrayList<Tree>(); IndexColumn for list semantic. public void plantTree(Tree tree) { trees.add(tree); } } // creates and persists a forest with 10.000 trees // new EntityManager and new transaction Tree tree = new Tree(“apple tree”); em.persist(tree); Orchard orchard = em.find(Orchard.class, id); orchard.plantTree(tree); 43 Tuesday, November 22, 2011
  • 60. OneToMany Mapping Seman&c Java  Type Annota&on java.u3l.Collec3on bag  seman3c java.u3l.List @ElementCollec3on  || @OneToMany  ||  @ManyToMany set  seman3c java.u3l.Set @ElementCollec3on  || @OneToMany  ||  @ManyToMany (@ElementCollec3on  || @OneToMany  ||  @ManyToMany)   list  seman3c java.u3l.List && (@OrderColumn  ||   @IndexColumn) @OneToMany  (no  cascade  op3on) 44 Tuesday, November 22, 2011
  • 61. OneToMany Mapping add   remove   update   element element element bag   re-­‐create: re-­‐create: 1  update seman3c 1  delete  +  N  inserts 1  delete  +  N  inserts set   1  insert 1  delete 1  update seman3c list   1  insert  +  M   1  delete  +  M   1  update seman3c updates updates* @OneToMany  (no  cascade  op3on) 45 Tuesday, November 22, 2011
  • 62. OneToMany Mapping add   remove   update   element element element bag   re-­‐create: re-­‐create: 1  update seman3c 1  delete  +  N  inserts 1  delete  +  N  inserts set   1  insert 1  delete 1  update seman3c list   1  insert  +  M   1  delete  +  M   1  update seman3c updates updates* @OneToMany  (no  cascade  op3on) 46 Tuesday, November 22, 2011
  • 63. OneToMany Mapping add   remove   update   element element element Oops, we have a problem. bag   (list: removal of nth element, n < size-2) re-­‐create: re-­‐create: seman3c 1  delete  +  N  inserts 1  delete  +  N  inserts 1  update set   1  insert 1  delete 1  update seman3c list   1  insert  +  M   1  delete  +  M   1  update seman3c updates updates* @OneToMany  (no  cascade  op3on) 47 Tuesday, November 22, 2011
  • 64. Anti-Pattern #4 Inadequate Collection Type (Owning Side) Tuesday, November 22, 2011
  • 65. Inadequate Collection Mapping (Owning Side) • Description –Chosen an inadequate collection mapping on the owning side • Consequences –Additional queries executed • Solution –Consider your use cases and usage patterns and choose a mapping with the least performance overhead 49 Tuesday, November 22, 2011
  • 66. Plant a Tree @Entity public class Forest { @Id @GeneratedValue private Long id; @OneToMany Set<Tree> trees = new HashSet<Tree>(); public void plantTree(Tree tree) { trees.add(tree); } } // creates and persists a forest with 10.000 trees // new EntityManager and new transaction Tree oak = new Tree(“oak”); em.persist(oak); Forest forest = em.find(Forest.class, id); forest.plantTree(oak); 50 Tuesday, November 22, 2011
  • 67. Anti-Pattern #5 OneToMany as Owning Side Tuesday, November 22, 2011
  • 68. OneToMany as Owning Side • Description –OneToMany used as the owning side of a relationship • Consequences –Collection elements loaded into memory –Possibly unnecessary queries –Transaction and locking schema problems: version, optimistic locking • Solution –Use ManyToOne as the owning side and OneToMany as the inverse side –Or at least exclude the collection from locking • @OptimisticLock(excluded=true) . 52 Tuesday, November 22, 2011
  • 69. Plant a Tree @Entity public class Forest { @Id @GeneratedValue private Long id; @OneToMany (mappedBy = “forest”) Set<Tree> trees = new HashSet<Tree>(); public void plantTree(Tree tree) { trees.add(tree); } } @Entity public class Tree { @Id @GeneratedValue private Long id; private String name; @ManyToOne Forest forest; public void setForest(Forest forest) { this.forest = forest; this.forest.plantTree(this); } } 53 Tuesday, November 22, 2011
  • 70. Plant a Tree @Entity public class Forest { @Id @GeneratedValue private Long id; @OneToMany (mappedBy = “forest”) Set<Tree> trees = new HashSet<Tree>(); public void plantTree(Tree tree) { trees.add(tree); } } @Entity public class Tree { @Id @GeneratedValue private Long id; private String name; @ManyToOne Forest forest; public void setForest(Forest forest) { this.forest = forest; this.forest.plantTree(this); } } 54 Tuesday, November 22, 2011
  • 71. Anti-Pattern #6 Inadequate Collection Type (Inverse Side) Tuesday, November 22, 2011
  • 72. Inadequate Collection Type (Inverse Side) • Description –Set used as a collection type on the inverse side of a relationship and, to keep the model consistent, the owning side updates the inverse side • Consequences –Due to a set semantic, all elements must be loaded when we add a new element • Solution –Use Collection or List instead 56 Tuesday, November 22, 2011
  • 73. Plant a Tree @Entity public class Forest { @Id @GeneratedValue private Long id; @OneToMany (mappedBy = “forest”) Collection<Tree> trees = new HashSet<Tree>(); public void plantTree(Tree tree) { trees.add(tree); } } @Entity public class Tree { @Id @GeneratedValue private Long id; private String name; @ManyToOne Forest forest; public void setForest(Forest forest) { this.forest = forest; this.forest.plantTree(this); } } 57 Tuesday, November 22, 2011
  • 74. Plant a Tree @Entity public class Forest { @Id @GeneratedValue private Long id; @OneToMany (mappedBy = “forest”) Collection<Tree> trees = new HashSet<Tree>(); public void plantTree(Tree tree) { trees.add(tree); } } @Entity public class Tree { @Id @GeneratedValue private Long id; private String name; @ManyToOne Forest forest; // ... } // creates and persists a forest with 10.000 trees // new EntityManager and new transaction em.remove(forest); 58 Tuesday, November 22, 2011
  • 75. Plant a Tree @Entity public class Forest { @Id @GeneratedValue private Long id; @OneToMany (mappedBy = “forest”) Collection<Tree> trees = new HashSet<Tree>(); public void plantTree(Tree tree) { trees.add(tree); } } @Entity public class Tree { @Id @GeneratedValue private Long id; private String name; @ManyToOne Forest forest; // ... } // creates and persists a forest with 10.000 trees // new EntityManager and new transaction em.remove(forest); 58 Tuesday, November 22, 2011
  • 76. Plant a Tree @Entity public class Forest { @Id @GeneratedValue private Long id; @OneToMany (mappedBy = “forest”) Collection<Tree> trees = new HashSet<Tree>(); // ... } @Entity public class Tree { @Id @GeneratedValue private Long id; private String name; @ManyToOne Forest forest; // ... } // creates and persists a forest with 10.000 trees // new EntityManager and new transaction for (Tree tree : forest.getTrees()) { tree.setForest(null); } 59 em.remove(forest); Tuesday, November 22, 2011
  • 77. Plant a Tree @Entity public class Forest { @Id @GeneratedValue private Long id; @OneToMany (mappedBy = “forest”) Collection<Tree> trees = new HashSet<Tree>(); // ... } @Entity public class Tree { @Id @GeneratedValue private Long id; 10.000 UPDATES private String name; @ManyToOne 1 DELETE Forest forest; // ... } // creates and persists a forest with 10.000 trees // new EntityManager and new transaction for (Tree tree : forest.getTrees()) { tree.setForest(null); } 59 em.remove(forest); Tuesday, November 22, 2011
  • 78. Anti-Pattern #7 One by One Processing Tuesday, November 22, 2011
  • 79. Inadequate Collection Type (Inverse Side) • Description –Sequential processing of a persistent collection/objects • Consequences –Each database operation performed separately for each element • Solution –Bulk queries –That’s why CaveatEmptor was implemented like this (aggregate function on a database level) 61 Tuesday, November 22, 2011
  • 80. Conclusions • Big data cause big problems –Standard mappings don’t handle large datasets well –Smart model, bulk processing, projections • RTFM –Most of information can be found in the hibernate docs –Understand what you read –Think about consequences –And hopefully you’ll be fine :) • Hibernate –Smarter policies and data structures 62 Tuesday, November 22, 2011
  • 81. Contact • email: patrycja@yonita.com • twitter: @yonlabs • www: http://www.yonita.com 63 Tuesday, November 22, 2011