6 Replies Latest reply on Apr 3, 2003 5:56 PM by mart

    LocalHome object is null and causes IllegalArgumentException

    mart

      Dear reader,

      I have encountered the following problem in JBoss 3.0.4.

      I have 2 tables (database), Address and PostalAddress. An Address can have a PostalAddress (or none). Thus 0..1 relation. Address therefore contains a foreign key that links to PostalAddress.

      Both are implemented using an entity bean (bean-managed persistance). In Address I have a method to set/get the stub of PostalAddress.

      public PostalAddressLocal getPostalAddressLocal() {
      return localPostalAddressFK;
      }

      public void setPostalAddressLocal(PostalAddressLocal localAddress) {
      this.localPostalAddressFK = localAddress;
      }

      Both methods are at the local interface of AddressBean.

      The error occurs as soon as ejbStore() is called. In ejbStore() the method getPostalAddressLocal() is called to get the postal address stub (and from that the primary key, which will be the foreign key). But the method returns null (as the stub is null, this address does not have a postal address). getPostalAddressLocal() is called on a local interface in ejbStore (the way it should be done normally) and not called directly. A final note: ejbStore() actually uses a different class to store itself, but nevertheless the problem is the same.

      The exact error thrown:

      ERROR [org.jboss.ejb.plugins.LogInterceptor] TransactionRolledbackLocalException, causedBy:
      java.lang.IllegalArgumentException: Attempt to remove a lock for a null object
      at org.jboss.ejb.BeanLockManager.removeLockRef(BeanLockManager.java:103)
      at org.jboss.ejb.plugins.EntityLockInterceptor.invoke(EntityLockInterceptor.java:124)
      at org.jboss.ejb.plugins.EntityCreationInterceptor.invoke(EntityCreationInterceptor.java:69)
      at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:107)
      at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:178)
      at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:60)
      at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:130)
      at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:204)
      at org.jboss.ejb.EntityContainer.invoke(EntityContainer.java:493)
      at org.jboss.ejb.plugins.local.BaseLocalContainerInvoker.invoke(BaseLocalContainerInvoker.java:301)
      at org.jboss.ejb.plugins.local.EntityProxy.invoke(EntityProxy.java:38)

      It seems it tries to unlock the stub when the method is called, but as it is null something goes wrong. Can anyone shed any light on this? Maybe I just can't use 'null' stubs and they always must be set. But then I would not know how to implement the relation sketched above.

      Thank you very much for your time!

        • 1. Re: LocalHome object is null and causes IllegalArgumentExcep

          The error message is misleading.
          It was fixed in 3.0.5 or 3.0.6, it should say
          "Attempt to obtain a lock for a null object"

          This means you are trying to invoke on an
          entity bean with a null primary key.

          I didn't follow your explanation so I'm not
          sure what you are doing wrong.

          Regards,
          Adrian

          • 2. Re: LocalHome object is null and causes IllegalArgumentExcep
            mart

            Hi Adrian,

            Thank you for your reply! Well I am not sure what I am doing wrong either. Maybe I am just trying the impossible. :)

            Let me try to be more exact. Let's show you exactly what I do (lot of code removed that is not relevant).

            class AddressBean extends GenericAttributeAccess implements EntityBean {

            private PostalAddressLocal localPostalAddressFK; // The foreign key stub
            private AddressJDBC database; // Class handling data-access

            public void ejbCreate(Map attributes) {
            setAttributes(attributes); // Store the attributes in GenericAttributeAccess
            database.insertEntity(attributes); // Insert the entity in the database, using the separate class
            }

            public void setEntityContext(EntityContext context) {
            this.context = context;

            // Create the database handler and pass it the local object of this bean
            database = new AddressJDBC((AddressLocal)entityContext.getEJBLocalObject());
            database.openConnection();
            }

            public void ejbStore() {
            database.storeEntity(attributes); // Now store the data
            }

            /**
            * Returns the postal address local stub if there is one, or null
            * if this class has no foreign key to PostalAddress.
            */
            public PostalAddressLocal getPostalAddressLocal() {
            return localPostalAddressFK;
            }

            /**
            * Sets the new postal address local stub
            */
            public void setPostalAddressLocal(PostalAddressLocal localAddress) {
            this.localPostalAddressFK = localAddress;
            }

            }


            public class AddressJDBC {

            private AddressLocal localAddress;

            public AddressJDBC(AddressLocal localAddress) {
            this.localAddress = localAddress;
            }

            public void insertEntity(Map attributes) {

            // Insert entity, works fine as I do not store the stubs yet
            }

            public void storeEntity(Map attributes) {

            // It goes wrong here, when I try to get the local-stub to store.
            // It seems to go wrong always, whether it is null or not...
            PostalAddressLocal localPostalAddress = localAddress.getPostalAddressLocal();

            // It then never reaches this statement
            if(localPostalAddres != null) {
            .....
            }
            }

            }


            The creation of the address is done in a stateless session bean's method.
            The bean has the following method:

            public void createAddress(...) {
            .... Location code of stubs

            // create the address, using a local stub as well
            localAddressHome.createAddress(attributes);

            // Sets the new postalAddress to use (local stub of postal address)
            // if there is one. The store() method in AddressBean is called
            // after this method. So the stub should be set.
            localAddressHome.setPostalAddress(postalAddress);
            }


            It seems to go wrong always, whether the postal address is set or not.
            The error is always in storeEntyity(..) at the same line as shown above.
            It seems the session bean somehow has locked something? Or the AddressBean
            itself?

            According to your answer 'Attempt to obtain a lock for a null object'
            it seems it wants to lock the stub. If it's null I can understand it goes
            wrong, but what if it's not null as shown in the example above? And still
            the question remains how to implement what I need (Address does not always
            have a reference to a PostalAddress).

            I hope you have an idea now, what's going wrong! Thanx a lot for your time!

            Regards Martijn

            • 3. Re: LocalHome object is null and causes IllegalArgumentExcep
              mart

              Hi Adrian,

              Thank you for your reply! Well I am not sure what I am doing wrong either. Maybe I am just trying the impossible. :)

              Let me try to be more exact. Let's show you exactly what I do (lot of code removed that is not relevant).

              class AddressBean extends GenericAttributeAccess implements EntityBean {

              private PostalAddressLocal localPostalAddressFK; // The foreign key stub
              private AddressJDBC database; // Class handling data-access

              public void ejbCreate(Map attributes) {
              setAttributes(attributes); // Store the attributes in GenericAttributeAccess
              database.insertEntity(attributes); // Insert the entity in the database, using the separate class
              }

              public void setEntityContext(EntityContext context) {
              this.context = context;

              // Create the database handler and pass it the local object of this bean
              database = new AddressJDBC((AddressLocal)entityContext.getEJBLocalObject());
              database.openConnection();
              }

              public void ejbStore() {
              database.storeEntity(attributes); // Now store the data
              }

              /**
              * Returns the postal address local stub if there is one, or null
              * if this class has no foreign key to PostalAddress.
              */
              public PostalAddressLocal getPostalAddressLocal() {
              return localPostalAddressFK;
              }

              /**
              * Sets the new postal address local stub
              */
              public void setPostalAddressLocal(PostalAddressLocal localAddress) {
              this.localPostalAddressFK = localAddress;
              }

              }


              public class AddressJDBC {

              private AddressLocal localAddress;

              public AddressJDBC(AddressLocal localAddress) {
              this.localAddress = localAddress;
              }

              public void insertEntity(Map attributes) {

              // Insert entity, works fine as I do not store the stubs yet
              }

              public void storeEntity(Map attributes) {

              // It goes wrong here, when I try to get the local-stub to store.
              // It seems to go wrong always, whether it is null or not...
              PostalAddressLocal localPostalAddress = localAddress.getPostalAddressLocal();

              // It then never reaches this statement
              if(localPostalAddres != null) {
              .....
              }
              }

              }


              The creation of the address is done in a stateless session bean's method.
              The bean has the following method:

              public void createAddress(...) {
              .... Location code of stubs

              // create the address, using a local stub as well
              localAddressHome.createAddress(attributes);

              // Sets the new postalAddress to use (local stub of postal address)
              // if there is one. The store() method in AddressBean is called
              // after this method. So the stub should be set.
              localAddressHome.setPostalAddress(postalAddress);
              }

              It seems to go wrong always, whether the postal address is set or not.
              The error is always in storeEntyity(..) at the same line as shown above.
              It seems the session bean somehow has locked something? Or the AddressBean
              itself?

              According to your answer 'Attempt to obtain a lock for a null object'
              it seems it wants to lock the stub. If it's null I can understand it goes
              wrong, but what if it's not null as shown in the example above? And still
              the question remains how to implement what I need (Address does not always
              have a reference to a PostalAddress).

              I hope you have an idea now, what's going wrong! Thanx a lot for your time!

              Regards Martijn

              • 4. Re: LocalHome object is null and causes IllegalArgumentExcep
                mart

                > The error message is misleading.
                > It was fixed in 3.0.5 or 3.0.6, it should say
                > "Attempt to obtain a lock for a null object"
                >
                > This means you are trying to invoke on an
                > entity bean with a null primary key.
                >
                > I didn't follow your explanation so I'm not
                > sure what you are doing wrong.
                >
                > Regards,
                > Adrian
                Actually this is the 3rd time I post it, but for some reason so far nothing is shown. Hope this one finally appears in the thread...


                Hi Adrian,

                Thank you for your reply! Well I am not sure what I am doing wrong either. Maybe I am just trying the impossible. :)

                Let me try to be more exact. Let's show you exactly what I do (lot of code removed that is not relevant).


                class AddressBean extends GenericAttributeAccess implements EntityBean {

                private PostalAddressLocal localPostalAddressFK; // The foreign key stub
                private AddressJDBC database; // Class handling data-access

                public void ejbCreate(Map attributes) {
                setAttributes(attributes); // Store the attributes in GenericAttributeAccess
                database.insertEntity(attributes); // Insert the entity in the database, using the separate class
                }

                public void setEntityContext(EntityContext context) {
                this.context = context;

                // Create the database handler and pass it the local object of this bean
                database = new AddressJDBC((AddressLocal)entityContext.getEJBLocalObject());
                database.openConnection();
                }

                public void ejbStore() {
                database.storeEntity(attributes); // Now store the data
                }

                /**
                * Returns the postal address local stub if there is one, or null
                * if this class has no foreign key to PostalAddress.
                */
                public PostalAddressLocal getPostalAddressLocal() {
                return localPostalAddressFK;
                }

                /**
                * Sets the new postal address local stub
                */
                public void setPostalAddressLocal(PostalAddressLocal localAddress) {
                this.localPostalAddressFK = localAddress;
                }

                }


                public class AddressJDBC {

                private AddressLocal localAddress;

                public AddressJDBC(AddressLocal localAddress) {
                this.localAddress = localAddress;
                }

                public void insertEntity(Map attributes) {

                // Insert entity, works fine as I do not store the stubs yet
                }

                public void storeEntity(Map attributes) {

                // It goes wrong here, when I try to get the local-stub to store.
                // It seems to go wrong always, whether it is null or not...
                PostalAddressLocal localPostalAddress = localAddress.getPostalAddressLocal();

                // It then never reaches this statement
                if(localPostalAddres != null) {
                .....
                }
                }

                }


                The creation of the address is done in a stateless session bean's method.
                The bean has the following method:


                public void createAddress(...) {
                .... Location code of stubs

                // create the address, using a local stub as well
                localAddressHome.createAddress(attributes);

                // Sets the new postalAddress to use (local stub of postal address)
                // if there is one. The store() method in AddressBean is called
                // after this method. So the stub should be set.
                localAddressHome.setPostalAddress(postalAddress);
                }


                It seems to go wrong always, whether the postal address is set or not.
                The error is always in storeEntyity(..) at the same line as shown above.
                It seems the session bean somehow has locked something? Or the AddressBean
                itself?

                According to your answer 'Attempt to obtain a lock for a null object'
                it seems it wants to lock the stub. If it's null I can understand it goes
                wrong, but what if it's not null as shown in the example above? And still
                the question remains how to implement what I need (Address does not always
                have a reference to a PostalAddress).

                I hope you have an idea now, what's going wrong or what I do wrong! Thanx a lot for your time!

                Regards Martijn

                • 5. Re: LocalHome object is null and causes IllegalArgumentExcep

                  What is the value of your primary key
                  at the end of ejbCreate?

                  Regards,
                  Adrian

                  • 6. Re: LocalHome object is null and causes IllegalArgumentExcep
                    mart

                    Hi Adrian,

                    Sorry my mistake. The method must be:


                    private PrimaryKey key;

                    public PrimaryKey ejbCreate(Map attributes) {
                    setAttributes(attributes);
                    key = database.insertEntity(attributes);
                    return key;
                    }


                    The key is a special primary key, it can contain compound fields (using a hashtable). Normally and in this case it just contains an autogenerated number from the database (mysql 3.5.x using BDB with auto-increment on). And that is all just fine. The primary key of addressbean is always generated properly.

                    Regards Martijn