2

Does anyone tried integrating spring-data-jpa with java-ee application? I'm using glassfish3 as an application container.

I followed an official spring-data-jpa tutorial and created a class:

public class EntityManagerFactoryProducer {

    @Produces
    @ApplicationScoped
    public EntityManagerFactory createEntityManagerFactory() {
        return Persistence.createEntityManagerFactory("myPU");
    }

    public void close(@Disposes EntityManagerFactory entityManagerFactory) {
        entityManagerFactory.close();
    }

    @Produces
    @RequestScoped
    public EntityManager createEntityManager(EntityManagerFactory entityManagerFactory) {
        return entityManagerFactory.createEntityManager();
    }

    public void close(@Disposes EntityManager entityManager) {
        entityManager.close();
    }
}

But when I try to deploy my application, I'm getting an exception:

Error occurred during deployment: Exception while preparing the app : Could not resolve a persistence unit corresponding to the persistence-context-ref-name [org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean/entityManager] in the scope of the module called [App]. Please verify your application.. Please see server.log for more details.
Command deploy failed.

What am I missing? Should I also have another configuration file or maybe some xml file?

slnowak
  • 1,719
  • 3
  • 17
  • 35
  • I think the problem might be that you do not have a persistence unit with name "myPU" declared in your persistence.xml. But I also do not think that this is the right approach. See my answer for details. – Gandalf Dec 14 '14 at 16:00
  • PU is declared properly. – slnowak Dec 14 '14 at 20:05

2 Answers2

2

Since you are in a Java EE Application Container you do not want to create your own Persistence instance. The example from the Spring Data documentation you used is for CDI environmets that do not have built in JPA support. Glasfish creates EntityManagerFactory and EntityManager for you. You only need to republish it as CDI bean. So in your case it is important to use the second example shown in the documentation:

public class EntityManagerProducer {

    @Produces
    @RequestScoped
    @PersistenceContext
    private EntityManager entityManager;
}
Gandalf
  • 2,321
  • 17
  • 28
1

It's a bit more tricky that what is told in official documentation. To handle properly a Spring Repository in a CDI env, you need to declare:

  • a dependent entity manager producer

    @Produces @Dependent @PersistenceContext 
    EntityManager entityManager;
    
  • a eager repository

    @Eager public interface TestRepository extends CrudRepository<TestEntity, Long>
    

Then you'll be able to @Inject the repository in a CDI managed Bean. If you don't use the @Dependent and the @Eager annotation, Spring will cause exceptions at the initialization of the repositories, leading to uncatch expcetions on the first request made against it.

References:

Community
  • 1
  • 1
JR Utily
  • 1,639
  • 1
  • 20
  • 34
  • the problem with @Dependent pseudo scope is that multiple entityManagers will be created per injection point (so per request too) – Ariel Carrera Jul 14 '19 at 06:04
  • 1
    In my case I used `@Dependent`, but not `@Eager` annotation and it worked. I am using Wildfly, but not Glassfish. – Alexandr Jan 08 '21 at 09:17
  • I'm not working on that anymore, it may have changed in the last 4 years :) – JR Utily Jan 09 '21 at 10:28