13 Replies Latest reply on Jul 9, 2011 8:47 PM by smarlow

    Non-Java EE (Spring) JPA/Hibernate and native Hibernate applications in AS7

    marius.bogoevici

      Following a discussion with Scott Marlow, I'm trying to summarize the issues encountered with respect to running Spring and native Hibernate applications in JBoss AS7, as well as some possible workarounds and solutions discussed via different channels (IRC, JIRA). The goal is to consolidate all these different topics in a single place.

       

      Group 1. Issues concerning non-Java EE JPA deployments

       

      A) If we have a deployment which contains a META-INF/persistence.xml which is not compatible with the requirement for container-managed persistence units (e.g. using RESOURCE_LOCAL transactions), the deployment will fail.

       

      In the past, it was possible to suppress the deployment of the persistence unit, by indicating JBoss to ignore the persistence unit definition file.

       

      The current workaround is to rename the persistence unit definition file, but ideally we should provide a less invasive fix.

       

      Possible solution(s):

      1) Create a mechanism for instructing JBoss to ignore certain files at deployment time - a prototype exists

      2) Create a mechanism for instructing JBoss to disable an entire subsystem at deployment time (e.g. JPA)

       

      1) is simpler to implement, 2) has the advantage that it provides a more comprehensive solution (e.g. 1) will not prevent annotation processing, currently, but 2) would) 

       

      B) Even if the workaround is applied and the persistence unit is not deployed, JBoss will scan the existing classes for @PersistenceUnit and @PersistenceContext annotations.  This is necessary for classes which need to be Java EE-injected. However, if these annotations are defined on classes which are not Java EE-injected and a persistence unit is not found, the deployment will still fail (no persistence unit found). For example, Spring applications may use the @PersistenceContext annotation on beans which are not Java EE-injected.

       

      The current workaround is to avoid the usage of @PersistenceContext in such scenarios. Again, we should provide a less invasive fix if possible.

       

      Possible solutions:

      1) Do not throw a deployment exception when @PersistenceContext is found but no persistence unit exists. Rather, mark the injection point as invalid and throw a runtime exception if a class bearing that injection point is put in use as a Java EE component. Generally speaking a deployment error would be preferrable, but in this case the decision making process yields false positives.

      2) Restrict @PersistenceContext annotation processing to classes which can be identified as Java EE components - this may be more difficult than expected due to the variety of scenarios and expensive checking (servlet artifacts, EJB, managed beans)

      3) Create a mechanism for instructing JBoss to disable an entire subsystem at deployment time (e.g. JPA)

       

      Group 2. Issues affecting all kinds of JPA deployments

       

      C) A deployment exception is currently thrown if @PersistenceContext and @PersistenceUnit annotations are found on methods which are not setters.

       

      While the Java EE specification indicates that only setter methods (besides fields) of container-managed objets are injection targets, for other frameworks (e.g. Spring) it is possible to extend injection support to other methods as well, on objects which are not container managed.

       

      Possible solutions:

      1) Ignore non-setter methods, the specification does not require an exception to be thrown in this case

       

       

      Group 3. Issues affecting native Hibernate applications

       

      D) Hibernate 3 was previously available on the CP. Applications migrating from older versions of JBoss AS will need to include a dependency on the org.hibernate module. However, due to API changes in Hibernate, some Hibernate 3 applications may not be able to work with Hibernate 4 (e.g. Spring 3 apps using LocalSessionFactoryBean).

       

      A possible workaround is to include Hibernate 3 in the deployment unit.

       

      Possible solutions:

      1) Provide an optional org.hibernate:3 module that those application can depend on.

       

      E) Decide when to include the Hibernate module and when not (affects hybrid EE/native Hibernate JPA applications)

      ... I will let Scott detail that use case.

        • 1. Re: Non-Java EE (Spring) JPA/Hibernate and native Hibernate applications in AS7
          swd847

          I created

          https://issues.jboss.org/browse/AS7-1031 to track this, and have a fix in my branch that does not throw exceptions unless the class is actually used as an EE component.

          • 2. Re: Non-Java EE (Spring) JPA/Hibernate and native Hibernate applications in AS7
            marius.bogoevici

            Great. So that solves points B) and C) above.

            • 3. Re: Non-Java EE (Spring) JPA/Hibernate and native Hibernate applications in AS7
              jaikiran

              Group 1. Issues concerning non-Java EE JPA deployments

               

              A) If we have a deployment which contains a META-INF/persistence.xml which is not compatible with the requirement for container-managed persistence units (e.g. using RESOURCE_LOCAL transactions), the deployment will fail.

              What error does it fail with?

              • 4. Re: Non-Java EE (Spring) JPA/Hibernate and native Hibernate applications in AS7
                jaikiran

                Marius Bogoevici wrote:

                 

                 

                 

                Group 3. Issues affecting native Hibernate applications

                 

                D) Hibernate 3 was previously available on the CP. Applications migrating from older versions of JBoss AS will need to include a dependency on the org.hibernate module. However, due to API changes in Hibernate, some Hibernate 3 applications may not be able to work with Hibernate 4 (e.g. Spring 3 apps using LocalSessionFactoryBean).

                 

                A possible workaround is to include Hibernate 3 in the deployment unit.

                AS7 ships with Hibernate 4, so applications that are meant for Hibernate 3 (I know there are a lot of them) will have to package the hibernate 3.x jars in their application. They should not add a org.hibernate module dependency since that would mean a dependency on Hibernate 4. There's a related discussion about this here http://lists.jboss.org/pipermail/seam-dev/2011-June/003782.html. I think at one point, Scott Marlow had some plans to add some Hibernate 3 module, but I'm not too sure.

                • 5. Re: Non-Java EE (Spring) JPA/Hibernate and native Hibernate applications in AS7
                  smarlow

                  I would like to keep shipping Hibernate 4 but also want to see the ability to integrate different persistence providers that are tagged with a version identifier.  The AS7 javax.persistence.spi.PersistenceProviderResolver should be able to contain multiple instances of the same provider with different version tags.  The packaging of the persistence provider should allow for additional integration classes to be specified (e.g. custom classes for scanning a VFS file url for entities or using jandex for faster annotation scanning).  A custom persistence.xml "version" property can be introduced to match the persistence providers version tag.

                   

                  If we were to do this via "module" packaging, Hibernate 3 could be resolve via a dropped in Hibernate 3 module.

                  • 6. Re: Non-Java EE (Spring) JPA/Hibernate and native Hibernate applications in AS7
                    marius.bogoevici

                    Right now, an obscure datasource error - for lack of a <jta-data-source/> it tries to connect to java:/. But regardless of that, you cannot bootstrap a server-side PU with a RESOURCE_LOCAL, the spec won't stand for that, right?

                    • 7. Re: Non-Java EE (Spring) JPA/Hibernate and native Hibernate applications in AS7
                      marius.bogoevici

                      That was exacly my point (that including org.hibernate is currently a no-no), but I want to document the possible solutions and workarounds on our side, otherwise it's hard to get a clear picture.

                       

                      I am also working on adding Spring 3 with Hibernate 4 (initially, via Snowdrop), but ideally migrating an application that previously relied on finding Hibernate 3 on the server side should be as simple as possible (and it is possible), and one of the solutions listed above (Hib 3 module for example) would be a pretty fast way to get things done.

                       

                      And what Scott suggests would be very cool indeed.

                      • 8. Re: Non-Java EE (Spring) JPA/Hibernate and native Hibernate applications in AS7
                        alesj

                        A custom persistence.xml "version" property can be introduced to match the persistence providers version tag.

                         

                        If we were to do this via "module" packaging, Hibernate 3 could be resolve via a dropped in Hibernate 3 module.

                        Why a custom "version" property?

                         

                        I would simply do this:

                        • is it Hibernate provider (no provider == Hibernate)
                          • is there explicit Hibernate module defined in jboss-deployment-structure.xml / attachments
                          • no explicit Hibernate module == the default used in AS7 -- v4
                        • do the same for other JPA providers
                          • for each provider define its module name; perhaps even ship few with AS7?
                          • have default versions, check for explicit diff module version
                        • 9. Re: Non-Java EE (Spring) JPA/Hibernate and native Hibernate applications in AS7
                          smarlow

                          Pros of a custom "version" property:

                          • It is configured in the same file as the persistence provider (easier to use if configured in one place)
                          • Different versions of the provider could be used from the same app (its arguable whether this is a safe practice, could be too much rope)

                          Cons: of a custom "version property:

                          • Duplicates what could already be done at the deployment level (via jboss-deployment-structure.xml)
                          • Ensuring the version property resolves to a valid persistence provider could be a pain.  A module reference is less likely to be wrong.
                          • Updating a production application persistence.xml might not be allowable.  It might be safer to just update the jboss-deployment-structure module references.

                           

                          Seems to me that either way could work, but point taken. 

                          • 10. Re: Non-Java EE (Spring) JPA/Hibernate and native Hibernate applications in AS7
                            teacurran

                            Has anyone figured out what to do about this?

                             

                            I am trying to port a Seam3 application from Jboss6 yo AS7. Everything seems to work but we have a module developed via a 3rd party. It is a jar that contains a persistence.xml with transaction-type="RESOURCE_LOCAL" and uses hibernate 3.6. the application is failing to start but is not giving any specific error other than "Composite operation failed and was rolled back. Steps that failed:" => {"Operation step-2" which is less than helpful.

                             

                            In Jboss 6. the application starts correctly and only loads the JTA persistence.xml at boot time. The RESOURCE_LOCAL units are loaded by hibernate the first time they are used.

                            • 11. Re: Non-Java EE (Spring) JPA/Hibernate and native Hibernate applications in AS7
                              smarlow

                              This sounds related but might be a different issue.  Moved to http://community.jboss.org/thread/169186

                              • 12. Re: Non-Java EE (Spring) JPA/Hibernate and native Hibernate applications in AS7
                                teacurran

                                I think it is the same thing. If a persistence.xml is defined as RESOURCE_LOCAL, then why does the container attempt to load it at all? and if the container does want to load it, why does it fail when it is properly configured with connection properties and the .war contains all of the relevant hibernate jars needed?  seems like it should just work like it does in Tomcat, Jboss 6, and Glassfish.

                                • 13. Re: Non-Java EE (Spring) JPA/Hibernate and native Hibernate applications in AS7
                                  smarlow

                                  Your right about RESOURCE_LOCAL being mentioned above (A) and in your app.  I would still like to know why your app failed to deploy/start correctly.  And continue from there.  After we understand that (via discussion in the other forum thread I opened), we can continue the discussion in this thread as to when RESOURCE_LOCAL units should be deployed/started.

                                   

                                  Thanks for your help with this issue.

                                   

                                  Scott