This forum is now a read-only archive. All commenting, posting, registration services have been turned off. Those needing community support and/or wanting to ask questions should refer to the Tag/Forum map, and to http://spring.io/questions for a curated list of stackoverflow tags that Pivotal engineers, and the community, monitor.

AnnouncementAnnouncement Module

Collapse

No announcement yet.

Spring JPA+Postgres Incantation without XML a total mysteryPage Title Module

Spring JPA+Postgres Incantation without XML a total mystery

I can't find any functioning way for Spring with Annotations to create and inject an EntityManager object for me, backed by JPA and Postgres.

Can anyone share the minimal set of @Bean methods in an @Configuration-annotated object to get JPA working against Postgres?

I've created a minimal test application in an ordinary Eclipse Java project to show my working so far. I think everything should be self explanatory (and the error is probably located) in App.java linked below.

In App I'm trying to create an AnnotationConfigApplicationContext and get it to use the annotated methods in App.Config as a factory for a DataSource and an EntityManagerFactoryInfo. Then I try to load an EntityManager bean from the ApplicationContext, thinking it has enough information to proceed.

Running my code triggers no errors until the terminal error "No unique bean of type [javax.persistence.EntityManager]" when I try to load the EntityManager bean

I'm sure I'm just doing the wrong thing, but I can't find a simple statement of the minimal chain of events/requirements to configure and inject an EntityManager into my App. Currently it seems to think there is no definition of an EntityManager despite the EntityManagerFactoryInfo object and DataSource object available.

I figure all I need to provide is a database, and the right incantation somewhere in annotations or maybe java BeanDefinition passing, after which everything will work like magic.

I've set up and tested the database, but the magic incantation is eluding me. My aim is to avoid mysterious unvalidated XML files so I'm focusing on Annotations, or maybe even direct Java calls if anyone knows how, to configure and trigger the DI.

After much trial and error, (and I really mean a lot), I've had to give up and throw myself on your mercy.

I'm trying to avoid loading in a million and one unnecessary things from a test application configured by Maven and reams of boilerplate XML to establish if Spring components can be used in a more comprehensible and selective way.

The core example code of the approach I'm using so far is available in the App file, and the libraries on the build path of the Eclipse project are shown in the listjars.txt file also linked below.

When I run this App as is, I get no errors until my explicit getBean(EntityManager.class) call fails with...

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefini tionException: No unique bean of type [javax.persistence.EntityManager] is defined: expected single bean but found 0:
at org.springframework.beans.factory.support.DefaultL istableBeanFactory.getBean(DefaultListableBeanFact ory.java:269)
at org.springframework.context.support.AbstractApplic ationContext.getBean(AbstractApplicationContext.ja va:1083)
at com.cefn.filesystem.App.run(App.java:46)
at com.cefn.filesystem.App.main(App.java:29)

...and the remainder of the source is available by browsing around the src directory in the github tree if that helps.

EPILOGUE

Constructors and other established java conventions normally steer you towards resolving dependencies, and prevent runtime failures.

I find that Spring's divergence from this approach makes it more or less impossible for me to identify the minimal functioning configuration for any object, and leaves failures silent until service objects are demanded.

For EntityManager and JPA there now seems to be a history of about a thousand different recommended ways to do it, all using arcane XML files and most of which are now deprecated, and there are many suggested alternatives even for the recommended routes.

How am I meant to approach this problem in general as I'm sure I'll run into it in other parts of Spring?

Comment

Thanks for taking the time to reply. As mentioned in the first line of the original post, I've been looking for an annotation-based solution. I'd prefer to avoid XML files everywhere.

I'll try to translate from your XML into actual Java code, but even this is pretty mysterious.

For example, it's not obvious to me how I create an @Bean LocalContainerEntityManagerFactoryBean which will be wired to an @Bean DataSource which is provided by a different method in the same @Configuration object.

Using XML seems like a massively retrograde step given the strengths of the Java type system and the compile-time (and incidentally run-time) checking which is therefore possible. It was perhaps worthwhile as a stopgap before Java 1.5 brought in Annotations, but surely superceded now. If there is still a case for using XML, I don't know what it is, assuming you're writing your own code.

Understanding what actual objects need to be brought into existence to do this simple job (making an EntityManager available) means I can either construct my own procedurally, or use DI and get the same result. Without this equivalence, it's hard to debug anything.

I feel the XML approach simply leaves huge opportunities for mystery as to the actual things and their relationships, since elements and attributes are opaquely translated into behaviours over factories and beans with no linked documentation.

Worse, updates to Java classes can be made which require changes somewhere in a monolithic XML configuration file; whilst using annotations directly on classes and methods mitigates this problem hugely. As I'm responsible for my colleagues' future with this system, I feel XML is absolutely the wrong way to go.

BTW does anyone else find that sessions time out after an incredibly short time on this forum (<< 1Hour), leading to lost posts.