Is using Java assertions appropriate for verifying JPA implementation - java

I'm working on an application with an (almost) vanilla Java EE 6 stack (EJB, JPA, JSF, etc.). We are hosting our application on Glassfish 3 and our persistence-related code is 100% pure JPA for now.
Unfortunately, one part of our application must use a stored procedure in an Oracle 10g database. To call this stored procedure, we've decided to use EclipseLink (the JPA implementation which is bundled with Glassfish).
As a (small) part of our code is now dependent on EclipseLink I wondered how to verify this dependency. The dependency isn't packaged with the application but it is assumed to be available on our deployment platform (i.e. Glassfish).
In my mind, our options are:
Don't do anything, just let it fail. I think this solution is sub-optimal as it's never made explicit that our code assumes the presence of EclipseLink.
Check for EclipseLink in an if-statement and throw a specific exception.
if (!JpaHelper.isEclipseLink(entityManager)) {
throw new InvalidJpaImplementationException();
}
Add an assertion which checks for EclipseLink and let it throw an exception if it fails.
assert JpaHelper.isEclipseLink(entityManager)) : "Blah!";
Would an assertion (option 3) be a valid solution? Would you prefer another solution? Which one, and why?

Since you're using JPA, I would not make the implementation EclipseLink specific (as it must conform to the JPA specification). One shouldn't care what JPA providers they're using.
Your code could break if you decide moving to (let's say) Hibernate (if you implement dependency verification). The whole purpose of the JPA specification is that the developer should never worry about the implementation vendor product at all.
If you want to use Eclipse Link's Stored Procedure, then I would suggest that you create an engine that would call a Stored Procedure, irrespective of the EntityManager. That way, it would still not worry about JPA implementation provider dependency whatsoever. An example of how to call StoredProcedure with Hibernate JPA can be found here.

Assertions can be disabled, which would break your code on error. Hence officially better no assert. Should in the future the other entity manager become removed, you still better remove the test instead of disabling the assert. Reason: you were in "luck" that the other JPA used another implementation. Maybe logging just for InvalidJpaImplementationException is simpler too.

Related

How to use Spring Data JDBC without annotations?

I'm working on a new project, using concepts like clean architecture, protecting my model and business rules from external dependencies and frameworks. Also, I prefer not to use traditional ORM libraries (like JPA/Hibernate) and have choose to use plain jdbc (through spring jdbctemplate).
It was going pretty well, but I'm getting tired of write 20x almost the same query for all my domain classes on a basic crud reposity. So, I take a look at Spring Data JDBC, but it appears that it's necessary to add annotations on my domain classes to make it work properly. I really don't want to do that, first because I want to make my domain cleaner as possible from any dependencies, and second because this is one of the (many) things I really dislike on JPA.
I was wondering that, the repository needs only 2 things: a rowmapper definition and the PK definition (and both could be defined at the repository itself) avoiding the complete use of annotations.
So, my question is there any way to use Spring Data JDBC without annotations?
No, there is no easy way to use Spring Data JDBC (https://spring.io/projects/spring-data-jdbc).
What you could do is to replace those classes that do the annotation interpretation (RelationalPersistentEntityImpl, and BasicRelationalPersistentProperty) and replace them with something that gets the information from elsewhere.
There is a different framework wich might fit the bill which is also named Spring Data JDBC 🤷‍♀️ https://github.com/nurkiewicz/spring-data-jdbc-repository
It seems pretty close to what you are looking for but it has its last commit 6 years ago and is archived on Github.

Is JPA enough to perform CRUD operations

For a few days, I have been researching JPA and Hibernate.
Now I got confused about JPA - Hibernate interactions.
I know JPA is a specifcation and Hibernate implements it. But the missing point is a working principles . I mean in a real application, what does hibernate do and what does jpa do ? I am trying to get below questions. Let me ask you;
Question 1 : Is JPA only abstract notion ? Does it consist of only interfaces? (I have observed that everyting is interafce in
javax.persistance package.)
Question 2 : Is JPA enough to perform CRUD operations ? (Is it possible to use JPA without Hibernate or etc.) If it does , why we need JPA providers such as Hibernate or etc. ?
Question 3 : And last one , I am searching for concrete something. I
need to know Database->JPA->Hibernate interaction. For
example while Saving and fetching something , What does happen in
background ?which one is performing database operations(hibernate or jpa) or which one is responsible for providing db connection ?
I mean, in jpa/hibernate based application , who is responsible for what?
Question 1:
Yes, exactly! JPA is just a specification as you already know. It only says what can be done but doesn't say how it should be done or doesn't implement any behaviour. You can use JPA annotations with javax.persistence classes but in the end when you run your application nothing will happen!
Question 2:
As I said above, JPA is just a blueprint saying what can be done. Hibernate, OpenJPA, Toplink etc. actually implement that specification. They perform the operations differently so there might be tradeoffs in speed etc. but all of them have to be able to perform the same set of operations specified by JPA. Some might give you more features but never less.
Question 3:
Again JPA isn't performing any actions, it just specifies what can be done. How it's done, how the code <-> db interaction is performed, what kind of SQL queries are created it's all implementation specific and will differ (for instance Hibernate might create different SQL queries for the same thing than OpenJPA). How your DB interactions are performed in the end is determined during runtime by the implementation (Hibernate). You can try to find it all in the documentations for the concrete implementation. You can also print the SQLs that are performed for instance.
You might ask "then why do I need JPA"? Well that's because you can (in theory!) change the implementation just by changing the jar on the classpath to a different library (i.e. from Hibernate to Toplink). In practice sometimes it's not that easy due to implementation specific features or how each implementation handles SQL queries, tables etc.
As you state JPA is just a specification, so there is no implementation but every Java EE container should support it ( implementation of JPA is included in application server ).
JPA implementations in Popular application servers :
Glassfish - EclipseLink (reference implementation)
JBoss - Hibernate
Websphere - JPA for WebSphere Application Server persistence, Apache OpenJPA
So when you are using application server you can use JPA interface to perform any CRUD operation through particular JPA implementation.
Tomcat does not support JPA out-of-the-box. You can use JPA in applications deployed on Tomcat only if these applications embed some JPA implementation. Or use Apache TomEE project which provide JavaEE features for Tomcat.
Remember that Hibernate has JPA implementation but also more addictional (cool) features. But if you are using only elements from JPA spec you can anytime easily switch to another JPA implementation.
As you mentioned yourself: JPA is a specification, Hibernate an implementation!
1: Yes, correct this is the technical part of the specification in form of Java Interfaces.
2: NO, JPA is not "enough", JPA can't do anything, it is just a specification.
3: An Interaction exists only between Hibernate and the Database (actually, there are other parts like the database driver involved, but don't mind...).
The idea behind this separation is you can write code that only uses the interfaces from javax.persistence. At one single place you (or maybe a container like an application server) define which implementation you want to use. This makes your application very portable, and you could choose to switch implementations as you like (theoretically, in practice it is never that easy...)

Configuring Hibernate to use JPA-style configuration without going into EE

I am in the process of troubleshooting a recent translation of EJB code to native Hibernate code (painful process, since EJB spoiled me so much with its convenience).
One thing I find troublesome is that Hibernate keeps its entity declarations in a hbm.xml file and then the configurations in separate files. While this isn't necessarily a big issue, the Netbeans wizard doesn't really let the developer to just click a button, detect, all the entities on the fly, and update the configuration file.
With persistence.xml, however, I can do that easily by just adding the classes and forget about it. Another good thing is that persistence.xml stores pretty much everything needed for the ORM aside from the class-specific annotations (which I am keeping).
With that said, is there any way for me to have Hibernate to (1) stay off EE and (2) use persistence.xml to get the connection, mapping, etc?
Also, a related question - CriteriaQuery is apparently a Java EE thing. One thing I really like about using EJB is that there are strong compile-time contraints. For instance, I can put ClassName_.myAttribute directly as a parameter in a CriteriaQuery, whereas if I use the Hibernate native "Criteria" object, I have to use "my_attribute" instead, which is not subjected to compile time integrity checks (Note: ClassName_.myAttribute maps to "my_attribute" on the table).
So is there anyway to keep that compile-time integrity?
Thanks.
Hibernate EntityManager can be used outside of a Java EE container. See http://docs.jboss.org/hibernate/core/4.0/hem/en-US/html_single/#architecture-javase.
Moreover, even with the Hibernate native API, since you're using annotations, you don't need any hbm.xml file. Just a central Hibernate config file listing the entities and some Hibernate properties.

Difference between Hibernate library and Hibernate JPA library

In the screen where you can add the Hibernate library to a project, there are two options, Hibernate and Hibernate JPA.
What is the difference between the 2? Googling did not provide an explanation.
I found this to provide a good explanation.
http://elope.wordpress.com/2007/09/06/difference-between-jpa-and-hibernate/
From the above blog:
So if i need to put in Concise words:
a) JPA is Persistence Api which your code should use.
b) JPA Api will pass on the call to actual peristence provider (ex:Hibernate/TopLink) to do the actual work.
c) If you are looking from Performance prespective ,it will be dependent on actual peristence provider (Hibernate/TopLink) and not on JPA as its just a wrapper layer.
d) If you are looking from code dependency prespective ,JPA makes more sense as your code is dependent on standard Java Api.
e) If you have used Hibernate then you will find that certain features are missing in JPA like criteria queries etc.This does not mean that you can’t write criteria query in your application, you need to get Session object from JPA Entity manager and now you are as good as in hibernate project.
But now your code is dependent on Specific impl (Hibernate),going forward you can see more things getting added in JPA (2.0)
f) Should you use JPA: My take is you should ,API is clean and although not everthing you need is their but is a good step forward.
I don't know what "screen" you mean, but in general you can use Hibernate directly (Hibernate API) or as a JPA provider. As JPA is a standard API one can code against this API and switch between implementations (Hibernate, EclipseLink, OpenJPA, ...). When using Hibernate API you are tied to this but you can utilize features that are not standardized by JPA.

Hibernate or JPA?

With Spring 3.0 is it recommended to use hibernate or JPA.What are the advantages and disadvantages of both of them when used with Spring 3.0 ?
Note : We are also suppose to use it with Spring Data Access.
I would say, JPA implementation provided by Hibernate. Why? Because
It would be easier to switch to some other JPA implementation later, if you you ever need to
Hibernate is the one of the major and most popular ORM around
Lot of books available
Extensive documentation, awesome reference material
Easy to get support on SO, and elsewhere
Actually, I don't mind to use Hibernate exclusive features too. I don't see any problem in sticking with Hibernate, just because its not an standard. And by the way, what makes you think Spring is standard. Its not, and you are fine with it, because it works. Similar thing can be said for Hibernate. Hibernate sometimes get hairy, if you don't know well what you are doing.
My preference is JPA with EclipseLink. Reasons:
JPA is standard, Hibernate is not
Use EclipseLink because JPA with Hibernate has some weird implementation. EclipseLink is also the reference implementation for JPA 2.0
Bozho: there are some that I found, unfortunately it is not so obvious because it only happens in some extreme cases. Some that I can think:
Convert JQL to CriteriaBuilder
ElementCollection works fine with JoinTable, which is wrong! ElementCollection should be accompanied by CollectionTable.
To be precise, you should use the Java Persistence API, and then you can use Hibernate as an implementation.
JPA without an implementation isn't worth anything.
JPA is a standard, so if you only use it's API, you can substitute Hibernate with some other JPA implementation. If you use some of Hibernate's specific API because you need functionality not provided with plain JPA, you'll have a vendor lock-in scenario, so you'll have to be careful about this.
It depends on our application.
If you are not sure that you will never need to change your persistence provider, it is strongly recommended to use JPA (2.0)
If you are sure that you never will change your persistence provider, than I recommend using JPA (2.0) too. But (only) in this case you have the possibility to use a proprietary feature of you choosen JPA-Provider, if you have a problem not solved by standard JPA. -- But use it wise, if you choose this way once, it is hard to go back!
Of course JPA is just an API - so you need an implementation of it. -- I used Hibernate as JPA provider, but mainly because I am allways in the second scenario (will never change it), and I needed additional features like Hibernate-Search and Envers.

Categories