Showing posts with label jpa. Show all posts
Showing posts with label jpa. Show all posts

Friday, May 9, 2014

Java EE and Unit testing, Arquillian to the Rescue! Even with Persistence.

As most programmers know, Unit testing is a good practice. You get a quick result if you broke something vital.

And in a simple POJO (Plain Old Java Object) it's not that difficult to make a Unit test, most IDE has JUnit integrated in them.

But what about JavaEE? Now you have a servlet-container, context and persistence to worry about.


There are several solutions for this, the one that I've been focusing on is Arquillian.
Arquillian is a JBoss Community project and development is sponsored by Red Hat, Inc.
http://arquillian.org/

It's a good idé to use Maven with Arquillian. One of the reasons is that you can have different profiles for different servers (glassfish, wildfly, embedded, remote, etc).

My opinions of Maven: http://java-viking.blogspot.com/2014/05/java-ee-maven-and-gradle.html

So Arquillian can simulate JARs or WARs. You can add config-files and classes (or packages).
It can even do persistence.

So i use my Datasource from the server, simulate a War and test it remotely to the server.
The test begins with making a transaction and adding values to the database, I do this with a Facade that Netbeans like to create for JPA Entities.

I've done a test with the findAll-method to see if I get a list with the correct size, and it worked lovely.

So now it's time to test all the important stuff. On my next project I will start with the testing-stuff first now that I know of its capabilities.


So what's next?

Next is to test Arquillian Drone. The Drone-extension is for testing the actual site. So my JSF-sites can actually have automated tests. The newest 2.0.0 (alpha) can even test for mobile.

The Drone can find elements by id and actually do stuff, like login in and testing what the response site is.

So my hours of re-deploying and testing the same thing over and over again feels like a bitter cup of tea right now.

So thats it for now, I have a lot of testing to do. I will also experiment with the managed and embedded server options. But it's always good to have a "remote" server that actually is the same as the release environment,


Comment if you need help with Netbeans, Wildfly and Arquillian, the IDE in the tutorials is Eclipse and uses EclipseLink instead of the Wildfly default (hibernate),

Monday, April 14, 2014

JPA: Hibernate Implementation "lazily initialize a collection"

Today I have struggled half a day with a frustrating problem.

I have a ManyToMany-relationship (JPA) with two Entities. Shop and Brand, it's also bidirectional.

Hibernate and Spring-veterans sees where I'm going with this...

If I want to get a Object of Shop from the database, everythings simple. But if I want to get the attribute that's the "ManyToMany" (in this case "Brand") I would get it as a form of Collection.

But here's the kicker: Hibernate has a lazy initialization of these kinds of collections. This is for saving a lot of data loading for every time you get a Shop-object from the database.

I wanted to have a JSF-form with my data and the possibility to update it (specifically the Brands). I wanted to use the selectManyCheckBox component in JSF.

So the Hell began here.

The specific exception I got was (I also got the role-error earlier):
javax.servlet.ServletException: failed to lazily initialize a collection, could not initialize proxy - no Session

You can set the annotation of the ManyToMany to suggest "EARLY" so that it loads all the collection-data with the regular.

And that solution didn't solve my problems. It feels like I almost tried every solution known to man to solve this problem. I did beans that sole purpose was to get the Brands as a list from the Shop and try to merge it with the data in the form and the update-bean.

Of course I tried to google solutions. 95% of the links led me to thinking it was the classic lazy-problem that the Hibernate-session closed before I got my collection data.

But something wasn't right. Because I actually got the data to show in the form correctly quite early. It was the update that caused the problem.

The update was a bean that held the data from the JSF-component, they were connected.
But why did a lazy-error show when it wasn't supposed to load the data but actually update it?

I tried View filter (Open View in Session-pattern), I tried Stateful beans with EXTEND persistance unit.


After half a day I stumble to Hatim Alimam's blog were he had the same problem (but with Primeface implementation).
http://blog.hatemalimam.com/hibernate-lazyinitializationexception-and-pselectcheckboxmenu/

It was a little <f:attribute> that was needed!
If I just put   <f:attribute name="collectionType" value="java.util.ArrayList" /> in the <f:selectManyCheckBox>    Everything worked!

So it wasn't really the classic Lazy-problem, but with that Exception-message, one might think so...

So I hope anyone that has the same problem I had either stumble to this blog or Hatim's.

Cheers!

Sunday, April 13, 2014

Wildfly Injection and JPA: troublesome

So I've been making a Webapplication with classic CRUD via JPA. The database is also used for login-functions. I use JSF with Facelets for View.

JSF can manage beans easily e.g (value="#{myBean.value}")

So I thought that the Bean could be a @Entity. I even have a book that use it like that.
I then Inject the bean in my Facade (a DAO) that should persist it.

I checked so that it had the values that I gave from the View (JSF-form).


But here's the kicker!

I get "java.lang.IllegalArgumentException: Unknown entity: myclass#$Proxy$_$$_WeldClientProxy".

I tried of writing the classes manually in the persistance.xml without any luck.

After a lot of digging, I learned that the Bean that Weld injects (I use Wildfly-server that uses Weld) you doesn't actually get a real instance of your bean. You get a Proxy. So I could get the values, but it was not seen as an Entity.

I confirmed this by making a manual instance of the bean and persisting it with the same Facade-code.

The only difference was the Injection.

So my solution was to make a controller bean which had a manually created field of the bean. And use that bean e.g (value="controllerBean.myBean.value")

The controller bean then used the Facade for persistance.

This solution works for me, the controller bean can then do some validation and more.

Fine and dandy!