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!

Sunday, April 6, 2014

Wildfly, Impressions and configs

I'm using the Wildfly Java server for my current projects. I have a little Raspberry cluster of them even (I'm going to update the post how to set them up).

So how do I feel about Wildfly?
It's more configuration then programming! But after some talking to developer-friends, that's actually much of Java EE in the beginning.


So the latest part of the project was to make a Login-function. I've made a simple function like this in PHP. So I thought "what the hell".

After some research I found that Java EE hade it built in the servlet (you can even hide it in a simple html-form if you name the components just right).

So I tried to make a "customized" login which would use a form rendered by JSF and sent the values to a JavaBean which would use the servlet-login method.

Sounds easy? Yeah, that was my weekend...

By using built in functions, you got to know all the magic that actually happens, which isn't the same for every Java server, but at least similar.

First you have to choose if your going to save the users in a file, database or LDAP.
You then need to setup the security-domain to use the right options. For me, I needed to use databases,
That meant to connect it to the right JNDI (Datasource for the Database) and this was actually the last piece of the puzzle to fall into place. Many sites write a JNDI that seems to differ from the regular, but nothing is different! Just use the regular JNDI.

For database-solution you need to save the users (passwords and all) and the different roles they have in the database. You then set the queries for users and there passwords in the same security-domain.

For Wildfly you then need to create/edit the jboss-web.xml file to set it to use this security-domain (the one you configured).

You can also set the encryption and hash-algorithm for the password in the security-domain.

Then comes the web.xml configuring. At least this is the same for the most servers.
Here you get to set which options and which pages will and role will demand login and which site is the login-site and an error-site for getting the error-message (can have different for different errors).

I haven't puzzeled together all the pieces and don't really know all the requirements yet, but hopefully I will puzzle it out soon.

Hopefully this is one of the bigger obstacles I will face for my little project.


Impressions of Wildfly so far:
Fast and has many options (standalone, standalone-full, domain, etc).
Neat admin-console, and a good CLI-console.
Bad error-messages from admin-page (unknown error) is a regular occurence.
New server so it doesn't have many sources with examples yet,
Lots of configurations that needs to be done, some which you can't do from the Admin-page.