8 Replies Latest reply on Jun 24, 2005 4:11 PM by murtuza52

    Reproducing entity tutorial without ShoppingCart.checkout me

    gesha1

      Does anybody understand what i'm asking?

        • 1. Re: Reproducing entity tutorial without ShoppingCart.checkou
          leonell

          My mean (and I am beginner in EJB3).
          May be does exist other way...

          There are two problems:
          1) We need obtain back the persitued entity to session bean.
          2) We cannot use persist() and merge() in one SB method to avoid duplicity in DB (feature or error?)

          And now some code and comments:
          1)
          We need to load object back after persist() and merge() method.
          For it we must call find() method and know unique ID.
          We change Order and LineItem entity bean to use client based ID generation (to know ID in session bean).

          For example for Order:

          private String id;
          
          public Order()
          {
           org.doomdark.uuid.UUIDGenerator ug;
           ug=org.doomdark.uuid.UUIDGenerator.getInstance();
           id=ug.generateTimeBasedUUID().toString();
          }
          
          @Id(generate = GeneratorType.NONE)
          public String getId()
          {
           return id;
          }
          public void setId(String id)
          {
           this.id = id;
          }
          


          For LineItem the same change.


          2)
          Code from Session bean:

          // First way (see client later)
          public void createNewOrder()
          {
           order = new Order();
           manager.persist(order);
           order = manager.find(Order.class, order.getId() );
          }
          
          // First way (see client later)
          public void buyWithMerge(String product, int quantity, double price)
          {
           order.addPurchase(product, quantity, price);
           manager.merge(order);
           order = manager.find(Order.class, order.getId() );
          }
          
          // Second way (see client later)
          public void buyWithPersist(String product, int quantity, double price)
          {
           if (order==null) createNewOrder();
           order.addPurchase(product, quantity, price);
          }
          
          // Second way (see client later)
          public void update()
          {
           manager.merge(order);
           order = manager.find(Order.class, order.getId() );
          }
          


          Code from client:

          Variant A (better way)
          sc.createNewOrder();
          sc.buyWithMerge("Intel Celeron 3GHz kit", 1, 110.0);
          sc.buyWithMerge("MB ASUS A654", 3, 89.0 );
          sc.buyWithMerge("DDR 512MB", 2, 64.0);
          


          Variant B
          sc.buyWithPersist("Intel Celeron 3GHz kit", 1, 110.0);
          sc.update();
          sc.buyWithPersist("MB ASUS A654", 3, 89.0);
          sc.update();
          sc.buyWithPersist("DDR 512MB", 2, 64.0);
          sc.update();
          


          Now it works as you expected.

          Leonell

          • 2. Re: Reproducing entity tutorial without ShoppingCart.checkou
            gesha1

            Hello leaonel!
            Thank you for your posting and for payning attention to what I asked!

            First I think that in your example changing the generator to NONE is not needed since the auto generated order id is available after the persist method.

            Myapproach to this issue is :

            public void buy(String product, int quantity, double price) {
             if (order == null) {
             order = new Order();
             order.addPurchase(product, quantity, price);
             manager.persist(order);
             } else {
             manager.refresh(order); // also works: order = manager.find(Order.class, order.getId());
             order.addPurchase(product, quantity, price);
             }
             }
            



            I have consiced a little bit your example and it looks like this
            public void buy(String product, int quantity, double price) {
             if (order == null) {
             order = new Order();
             order.addPurchase(product, quantity, price);
             manager.persist(order);
             } else {
             order.addPurchase(product, quantity, price);
             manager.merge(order);
             order = manager.find(Order.class, order.getId());
             }
             }
            

            Client is not changed.

            They both works fine. You have an additional merge operation.
            I wander which way is more effective?

            And what I wanted is to achieve successfull merging without refreshing or refinding the instance, because the merge doesn't make any sence when used before a find or refresh, and doubles the LineItem when used after a find or refresh.


            • 3. Re: Reproducing entity tutorial without ShoppingCart.checkou
              leonell

              Hello,
              I created small test with insert of 1000 orders, every with 1-20 items.
              Here is my results:

              merge()+find() is 4 times slower then one persist per order (original example).
              refresh() is 6 times slower then one persist per order (original example).

              It means that more efective is merge+find because refresh is slowly than merge+find.

              I tested it with Preview 5 on MySQL 3 and Firebird SQL server.

              Leonell

              • 4. Re: Reproducing entity tutorial without ShoppingCart.checkou
                gesha1

                Hello leonell.
                How about find without merge?
                I mean this :

                public void buy(String product, int quantity, double price) {
                 if (order == null) {
                 order = new Order();
                 order.addPurchase(product, quantity, price);
                 manager.persist(order);
                 } else {
                 order = manager.find(Order.class, order.getId());
                 manager.merge(order);
                 }
                 }
                

                This code works correct. I wander what is the difference between find and refresh since they produce the same efect?

                • 5. Re: Reproducing entity tutorial without ShoppingCart.checkou
                  gesha1

                  Ooops There is a mistake! Sorry
                  Here is the correct code

                  public void buy(String product, int quantity, double price) {
                   if (order == null) {
                   order = new Order();
                   order.addPurchase(product, quantity, price);
                   manager.persist(order);
                   } else {
                   order = manager.find(Order.class, order.getId());
                   order.addPurchase(product, quantity, price);
                   }
                   }
                  


                  • 6. Re: Reproducing entity tutorial without ShoppingCart.checkou
                    leonell

                    One persist() on end of order ... 100%
                    Only find() before add() ... 400%
                    merge()+find() after add() ... 465%
                    refresh() before add() ... 688%

                    Leonell

                    • 7. Re: Reproducing entity tutorial without ShoppingCart.checkou
                      leonell

                      Hello,
                      when you add @org.jboss.ejb3.entity.LongLived before EntityManager then it will work fine and without find().

                      With LongLived and without find() is time 2x longer then persist() only.

                      It mean:

                       public void buy(String product, int quantity, double price)
                       {
                       if (order == null)
                       {
                       order = new Order();
                       order.addPurchase(product, quantity, price);
                       manager.persist(order);
                       }
                       else
                       {
                       order.addPurchase(product, quantity, price);
                       }
                       }
                      


                      And now why it works without find():

                      After calling .persist() is our entity managed and persisted but only to end of transaction and it mean to end of current method call. Then is entity detached. And with new method call we must call .find() to make entity managed again.

                      Annotation @LongLived marks the injected EntityManager to act like an Application Transaction. In JIRA is information that this annotation will be changed to PersistenceContext.

                      Leonell

                      • 8. Re: Reproducing entity tutorial without ShoppingCart.checkou
                        murtuza52

                        The different combination of merge+find and refresh() works fine. It is the performance issue only and i hope as EJB3 evolve there is a clear line on how this should be handled.

                        Currently i am trying to extend the code to apply for updates and delete of lineitem from the order. I am facing difficulty as adding new lineitem works fine but any change in "lineitem" entity or deleting a lineitem from the order will not be persisted or is not managed by EntityManager.

                        Here is the code:
                        /*
                        * JBoss, the OpenSource J2EE webOS
                        *
                        * Distributable under LGPL license.
                        * See terms of license at gnu.org.
                        */
                        package com.kt.order.entity.bean;

                        import javax.persistence.EntityManager;
                        import javax.ejb.Inject;
                        import javax.ejb.Remove;
                        import javax.ejb.Stateful;
                        import javax.persistence.EntityManager;


                        @Stateful
                        public class ShoppingCartBean implements ShoppingCart
                        {
                        @Inject
                        private EntityManager manager;
                        private Order order;

                        public void buy(String product, int quantity, double price)
                        {
                        if (order == null)
                        {
                        order = new Order();
                        System.out.println("Creating New Order");
                        }
                        System.out.println("Order: " + order.getId());
                        order.addPurchase(product, quantity, price);
                        }

                        public void remove(String product)
                        {
                        order.removePurchase(product);
                        }

                        public Order getOrder()
                        {
                        return order;
                        }

                        @Remove
                        public void checkout()
                        {
                        manager.persist(order);
                        }

                        public void update() throws Exception
                        {
                        manager.merge(order);
                        findOrderById(order.getId());
                        }

                        public Order findOrderById(int id) throws Exception
                        {
                        order = manager.find(Order.class, id);
                        System.out.println("findOrderById: " + order.toString());
                        return order;
                        }
                        }


                        The order.removePurchase(product); is simple method i have defined in the Order entity to remove any matching lineitem from the collection. Here is the code:
                        public void removePurchase(String product)
                        {
                        if(lineItems.size()>0)
                        {
                        for (LineItem item : lineItems)
                        {
                        if(item.getProduct().equalsIgnoreCase(product))
                        {
                        lineItems.remove(item);
                        System.out.println("Removing: " + item.getId() + " " + item.getProduct());
                        break;
                        }
                        }
                        }
                        }


                        Here is the client code which i am using for testing. The testNew(), testAdd() works fine but testEdit() and testDelete() is not working.

                        package com.kt.test.order;

                        import com.kt.order.entity.bean.LineItem;
                        import com.kt.order.entity.bean.Order;
                        import com.kt.order.entity.bean.ShoppingCart;

                        import javax.naming.InitialContext;

                        /**
                        * Comment
                        *
                        * @author Bill Burke
                        * @version $Revision: 1.1 $
                        */
                        public class OrderClient
                        {
                        public static void main(String[] args) throws Exception
                        {
                        SecurityManager security = System.getSecurityManager();
                        InitialContext ctx = new InitialContext();
                        ShoppingCart cart = (ShoppingCart) ctx.lookup(ShoppingCart.class.getName());

                        //testNew(cart);
                        //testAdd(cart);
                        testEdit(cart);
                        //testDelete(cart);
                        }

                        public static void testNew(ShoppingCart cart) throws Exception
                        {
                        System.out.println("Buying 2 memory sticks");
                        cart.buy("Memory stick", 2, 500.00);
                        System.out.println("Buying a laptop");
                        cart.buy("Laptop", 1, 2000.00);

                        System.out.println("Print cart:");
                        //Order order = cart.findOrderById(1);
                        Order order = cart.getOrder();
                        System.out.println("Total: $" + order.getTotal());
                        for (LineItem item : order.getLineItems())
                        {
                        System.out.println(item.getQuantity() + " " + item.getProduct() + " " + item.getSubtotal());
                        }

                        System.out.println("Checkout");
                        cart.checkout();
                        }

                        public static void testAdd(ShoppingCart cart) throws Exception
                        {
                        Order order = cart.findOrderById(1);
                        System.out.println("Adding a camcorder");
                        cart.buy("Cam", 3, 250.00);

                        System.out.println("Print cart:");
                        //Order order = cart.findOrderById(1);
                        //Order order = cart.getOrder();
                        System.out.println("Total: $" + order.getTotal());
                        for (LineItem item : order.getLineItems())
                        {
                        System.out.println(item.getQuantity() + " " + item.getProduct() + " " + item.getSubtotal());
                        }

                        System.out.println("Checkout");
                        cart.update();
                        }

                        public static void testEdit(ShoppingCart cart) throws Exception
                        {
                        Order order = cart.findOrderById(1);

                        System.out.println("Print cart:");
                        System.out.println("Total: $" + order.getTotal());
                        for (LineItem item : order.getLineItems())
                        {
                        if(item.getId()==3)
                        {
                        System.out.println("Changing cam name");
                        item.setProduct("Webcam");
                        }
                        System.out.println(item.getQuantity() + " " + item.getProduct() + " " + item.getSubtotal());
                        }

                        System.out.println("Checkout");
                        cart.update();
                        }

                        public static void testDelete(ShoppingCart cart) throws Exception
                        {
                        Order order = cart.findOrderById(1);

                        System.out.println("Print cart:");
                        System.out.println("Total: $" + order.getTotal());
                        for (LineItem item : order.getLineItems())
                        {
                        if(item.getId()==3)
                        {
                        //cart.remove(item.getProduct());
                        order.getLineItems().remove(item);
                        }
                        System.out.println(item.getQuantity() + " " + item.getProduct() + " " + item.getSubtotal());
                        }

                        System.out.println("Checkout");
                        cart.update();
                        }

                        }


                        Can anybody help me to find out how we can edit a lineitem or delete a lineitem from the Order.

                        Thanks in advance

                        Murtuza