users@jersey.java.net

Re: One Resource class for two URLs

From: Martin Probst <mail_at_martin-probst.com>
Date: Tue, 22 Apr 2008 14:00:23 +0200

Hi,

I've written up how this all works for me here:

http://www.martin-probst.com/blog/2008/04/22/wiring-up-jersey-jax-rs-hibernate

Maybe I should add that to the FAQ? It's not actually _frequently_
asked apparently, but it might still be a useful resource.

> Look at the 311 specification and sections 3.1.1 and 3.1.2:
>
> 3.1.1 Lifecycle and Environment 9
> [ ... ]
>
> 3.1.2 Constructors
> [ ... ]

Thanks for the pointer.

> We need to update Jersey to conform fully to this, currently it is
> not very smart about picking the constructor. So i think you will be
> OK as long as the spec stays the same.

Yes, I noticed that it will basically take the Constructor with the
most arguments (or at least that's what it did for me), even if they
aren't annotated.

> Is your HibnernateComponentProvider.getInstance(Scope scope,
> Constructor<T> contructor, Object[] parameters) method ignoring the
> "constructor" method parameter and using the default (empty)
> constructor of the class ?

Kind of. I do not use the constructor iff:
* the constructor's declaring class has an @Entity annotation and
* there is exactly one parameter
* the parameter is an instanceof Serializable

In that case I'll use Hibernate to instantiate the class, which in
turn will use an empty default constructor if present, or black magic
reflection/byte code manipulation voodoo stuff (well, I think ;-)) if
not.

In any other case I'll assume that I'm not really responsible for this
call, so I delegate to the actual constructor. I could also create my
own annotation to make this more explicit to the user, i.e.
@LoadFromPersistence or something on the constructor.

So this appears to be safe. Nice!

>> I fear that my solution simply exploits the undocumented current
>> behaviour and might break later on. Maybe this could be a bit
>> formalized, so people can supply Factory methods for their
>> Resources easily (which is essentially what I'm doing).
>
> How would the developer specify what the constructor parameters
> (e.g. @*Param) would be for the factory?
>
> Are you relying on a general pattern the the same template variable
> names etc?

Currently I don't do anything. And you're right, the parameters would
be problematic. Also, a ComponentProvider is probably the best
solution for this problem, which is basically dependency injection.

>> I still need to inject classes in the persistence layer for my
>> methods that search resources (e.g. by title) using direct
>> Hibernate queries, so classes might get injected by Jersey twice,
>> but I think this shouldn't be a problem.
>
> Jersey will ignore any non-null fields.

Ok, so no trouble there.

Thanks for your help,
Martin