I have a SEAM app with some JPA/Hibernate entities. And I now wonder where to put my query, persistence methods.
The default choice seems to put them in a session bean layer with injected
#PersistenceContext(...) #Inject EntityManager entityManager;
But I think I would rather have the methods on the entities themselves. What are the pro's/con's?
Testablity?
Niceness?
Performance?
And does anyone have links to best practices for interacting with the EntityManager etc. from methods on the Entities rather than session beans?
Best,
Anders
I have no experience with SEAM, but from my experience with Java projects, I found it easiest to keep beans clear of persist methods. What we usually do:
Have beans for business objects (like "User" and "Setting" for example)
Have a DAO layer which can persist and retrieve these beans (simple CRUD)
Have a Service Layer which nows how to handle the beans, and maybe even how to build an aggregate of beans
This way, everything is pretty separated, and is easy to unittest. Performance is usually not an issue with this setup.
Yes, that is also what I have done before.
In general, I think, EJB is insanely verbose and boilerplate'y, but SEAM actually helps a bit, so that is why, in my current project, the extra layer of session beans just to query and persist annoys me. I have the feeling that I could make a reasonably concise app if I could kill this layer...
Related
As far as I know, there are two ways to configure JPA / Hibernate:
XML based configuration through something like hibernate.cfg.xml. I don't like his approach because, well, XML ...
Through annotations in the entity object. Much better than the XML config, but it couples my entities to JPA.
As I am currently investigating an architecture where the domain model does not know anything about the database (The 'Onion' architecture), I am looking for is a way to specify the mappings without changing my entities.
Of course I could create separate mapping classes, e.g. if I have a Customer domain object, create a JPA-annotated CustomerEntity and let the repository translate from one to another. But this approach doesn't feel quite right because the Customer and CustomerEntity will essentially be the same.
So it seems like I have to resort to Hibernate XML configuration, but as mentioned before, I don't like that approach.
Spring has a nice way of configuration: Java-based configuration. I was wondering if there is something similar for Hibernate/JPA configuration, and if not, why not?
My apologies if none of the above makes sense, but any help is welcome, even if it doesn't answer my question :-)
I've never heard of an Onion Theory of Java EE design. I did hear of The Onion, but that's a satirical newsletter (if that :-). Separation of concerns in Java EE I typically expressed as a MVC, or Model View Controller architecture. Your JSP or JSF pages will be your view, your #ManagedBean controllers will be your controllers, and your model will hold your Entities.
The model, which is where the JPA will be, can usually be further separated into a Service Layer, a Persistence Layer and EIS (Enterprise Information System) or Database tier. The Service tier will hold your EJBs, annotated with Stateless, Statefull or Singleton, and will encapsulate the business logic for the application. The Persistence Layer will have #Entity annotated objects that are stored by the Database.
Java EE defines these layers with JSR's, with numbers of some sort. For example, the Java Persistence API (JPA) is JSR-220. Tests are developed against these JSR's and if a vendor meets these tests then their product can be (More or less) swapped out for another vender's version.
Apparantly there is somethinig called Fluent NHibernate for C#, which does exactly what I was looking for.
Unfortunately, there seems to be no "Fluent Hibernate" for Java.
There is a fluent-hibernate project on GitHub, but that one seems to be about fluently writing HQL-queries, not about mapping configurations.
I'm a little confused by the mixed use of JSF2+Spring+EJB3 or any combination of those. I know one of the Spring principal characteristics is dependency injection, but with JSF managed beans I can use #ManagedBean and #ManagedProperty anotations and I get dependency injection functionality. With EJB3 I'm even more confused about when to use it along with JSF or if there is even a reason to use it.
So, in what kind of situation would it be a good idea to use Spring+JSF2 or EJB3+JSF2?
Until now I have created just some small web applications using only JSF2 and never needed to use Spring or EJB3. However, I'm seeing in a lot of places that people are working with all this stuff together.
First of all, Spring and EJB(+JTA) are competing technologies and usually not to be used together in the same application. Choose the one or the other. Spring or EJB(+JTA). I won't tell you which to choose, I will only tell you a bit of history and the facts so that you can easier make the decision.
Main problem they're trying to solve is providing a business service layer API with automatic transaction management. Imagine that you need to fire multiple SQL queries to perform a single business task (e.g. placing an order), and one of them failed, then you would of course like that everything is rolled back, so that the DB is kept in the same state as it was before, as if completely nothing happened. If you didn't make use of transactions, then the DB would be left in an invalid state because the first bunch of the queries actually succeeded.
If you're familiar with basic JDBC, then you should know that this can be achieved by turning off autocommit on the connection, then firing those queries in sequence, then performing commit() in the very same try in whose catch (SQLException) a rollback() is performed. This is however quite tedious to implement everytime.
With Spring and EJB(+JTA), a single (stateless) business service method call counts by default transparently as a single full transaction. This way you don't need to worry about transaction management at all. You do not need to manually create EntityManagerFactory, nor explicitly call em.getTransaction().begin() and such as you would do when you're tight-coupling business service logic into a JSF backing bean class and/or are using RESOURCE_LOCAL instead of JTA in JPA. You could for example have just the following EJB class utilizing JPA:
#Stateless
public class OrderService {
#PersistenceContext
private EntityManager em;
#EJB
private ProductService productService;
public void placeOrder(Order newOrder) {
for (Product orderedproduct : newOrder.getProducts()) {
productService.updateQuantity(orderedproduct);
}
em.persist(newOrder);
}
}
If you have a #EJB private OrderService orderService; in your JSF backing bean and invoke the orderService.placeOrder(newOrder); in the action method, then a single full transaction will be performed. If for example one of the updateQuantity() calls or the persist() call failed with an exception, then it will rollback any so far executed updateQuantity() calls, and leave the DB in a clean and crisp state. Of course, you could catch that exception in your JSF backing bean and display a faces message or so.
Noted should be that "Spring" is a quite large framework which not only competes EJB, but also CDI and JPA. Previously, during the dark J2EE ages, when EJB 2.x was extremely terrible to implement (the above EJB 3.x OrderService example would in EJB 2.x require at least 5 times more code and some XML code). Spring offered a much better alternative which required less Java code (but still many XML code). J2EE/EJB2 learned the lessons from Spring and came with Java EE 5 which offers new EJB3 API which is even more slick than Spring and required no XML at all.
Spring also offers IoC/DI (inversion of control; dependency injection) out the box. This was during the J2EE era configured by XML which can go quite overboard. Nowadays Spring also uses annotations, but still some XML is required. Since Java EE 6, after having learned the lessons from Spring, CDI is offered out the box to provide the same DI functionality, but then without any need for XML. With Spring DI #Component/#Autowired and CDI #Named/#Inject you can achieve the same as JSF does with #ManagedBean/#ManagedProperty, but Spring DI and CDI offers many more advantages around it: you can for example write interceptors to pre-process or post-process managed bean creation/destroy or a managed bean method call, you can create custom scopes, producers and consumers, you can inject an instance of narrower scope in an instance of broader scope, etc.
Spring also offers MVC which essentially competes JSF. It makes no sense to mix JSF with Spring MVC. Further Spring also offers Data which is essentially an extra abstraction layer over JPA, further minimizing DAO boilerplate (but which essentially doesn't represent the business service layer as whole).
See also:
What exactly is Java EE?
JSF Controller, Service and DAO
#Stateless beans versus #Stateful beans
There's no real easy answer here as Spring is many things.
On a really high level, Spring competes with Java EE, meaning you would use either one of them as a full stack framework.
On a finer grained level, the Spring IoC container and Spring Beans compete with the combination of CDI & EJB in Java EE.
As for the web layer, Spring MVC competes with JSF. Some Spring xyzTemplate competes with the JPA interfaces (both can use eg Hibernate as the implementation of those).
It's possible to mix and match; eg use CDI & EJB beans with Spring MVC, OR use Spring Beans with JSF.
You will normally not use 2 directly competing techs together. Spring beans + CDI + EJB in the same app, or Spring MVC + JSF is silly.
I am trying to use the org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy in my Spring project, but I am not sure how to use it or whether it's exactly what I am looking for. I realize it can help make my DAOs work with a plain JDO PersistenceManagerFactory. Another question is: what happens if the proxy doesn't get made properly? Can I still use it to access my factory to create a transaction aware persistence manager? If the object managed by the factory is a singleton, does this change things? Why not just access the PersistenceManagerFactory directly? Perhaps PersistenceManagerFactoryUtils.getPersistenceManager would be more suited to my needs? Can getObject return null?
Answers are directly available on documentation
I realize it can help make my DAOs work with a plain JDO PersistenceManagerFactory.
Yes.
TransactionAwarePersistenceManagerFactoryProxy proxy allows DAOs to work with a plain JDO PersistenceManagerFactory reference, while still participating in Spring's (or a J2EE server's) resource and transaction management.
You can surely use it in your app. But without knowing your exact needs, we can't confirm any further.
Can I still use it to access my factory to create a transaction aware persistence manager
DAOs could seamlessly switch between a JNDI PersistenceManagerFactory and this proxy for a local PersistenceManagerFactory.
If the object managed by the factory is a singleton, does this change things? Why not just access the PersistenceManagerFactory directly?
It is usually preferable to write your JDO-based DAOs with Spring's JdoTemplate, offering benefits such as consistent data access exceptions instead of JDOExceptions at the DAO layer. However, Spring's resource and transaction management (and Dependency Injection) will work for DAOs written against the plain JDO API as well.
We have a hard situation.
There is a large project which uses hibernate special features so cannot quit hibernate.
We are to add Activiti process engine to the project in embedded mode and make use of JPA extensions (which only works with EntityManager)
Some entities should not be present in JPA persistent unit because as activiti documentation says all entities must have #Id and cannot use #IdClass/#EmbeddedId so we have to exclude such entities from persistent unit
We wish to use one shared transaction manager for EntityManager and Session. Also the dataSources are identical (or even shared)
Everything is Spring!
All this effort is to enable Activiti to use EntityManager for its JPA extension while letting existing hibernate dependent codes to continue work.
First off, your 3rd point above may prove tricky to accommodate if you want to have one persistence unit and you're actually using #IdClass/#EmbeddedId in your Hibernate entities. Here are two possible solutions:
Pull JPA into your project and configure a persistence unit for your existing Hibernate entities, but continute to delegate the existing calls to Hibernate by accessing the Session directly. In this case, your configuration would be moved over to JPA, but your code would not. This approach also assumes that you have some reasonable abstraction dispensing Session objects in a pluggable fashion. See this question for the crux of the solution. If you have zero flexibility on point 3 above, this approach may not be an option for you.
Create both a session factory and persistence unit and coordinate transactions using JTA with two XA datasources. Even though your data may reside in the same database, you'll want to make sure you create distinct datasources in your configuration if you take this approach. This will prevent Spring's transactional proxy from getting confused when you participate in the distributed transaction. This is probably the cleanest approach, but does carry the stigma of XA transactions which, depending on your container, is more of a political problem these days than a technical one.
I've been working in Glassfish 3, JPA and Java EE 6. In a web container you can just inject the Entity Manager into an EJB and let that handle your transactions, rollbacks, etc. What do I do in a desktop application. Obviously that does not work. I know I would still use JPA for ORM. But would I create an EntityMangerFactory and then create an Entitymanager from that? Would I have to handle my transactions manually? It would great if I could see some sample applications. Thanks!
EntityManagerFactory entityManagerFactory =
Persistence.createEntityManagerFactory("DS");
em = entityManagerFactory.createEntityManager();
You have to handle transactions, by calling em.getTransaction.begin() and em.getTransaction.commit(), if you don't use the spring-framework or something else.
Well i suggest to try using Spring +JPA, there you do not need a container ,it is just the application context and you can configure transactions there.
You will not take care of the transactions ,just annotate your methods that you want to be #Transactional.
You could use Spring, this will bring you the plesent you know from JEE6 to desktop applications. (Of course it is not 100% the same!)
Another option could be to use so called Embeddable EJB Container. It could provide you same services as injection, CMT etc which you might be accustomed to.
I've built a 2-tier Java Swing client using Hibernate and Swing, and I will never do it again. If I had to rebuild it today, I would use raw JDBC queries, or maybe a very thin ORM mapping framework like iBatis.
The reason that Hibernate (and I assume other JPA implementations, although my experience is only with Hibernate) is so different in a desktop environment is 1) because objects tend to have a much longer lifespan on the desktop, and 2) it's very hard to know when an object will be accessed, so correct transaction handling for lazy loading is problematic.
The web request-response paradigm is fundamentally transactional, so it's very easy to demarcate your transactions there. On the desktop, every keypress, even just a MouseMovedEvent, could potentially trigger a database query or lazy load, so it's much harder to know when to initiate and commit transactions.
Error handling and object refreshing is a big problem, since objects tend to have a much longer life (often for the duration of the application launch). In Hibernate, exceptions are non-recoverable, which means that you're supposed to reload everything from the db. This is fine on the web, but definitely not fine when you have thousands of objects embedded in various models throughout your GUI.