spring hibernate injection

E

eunever32

Hi

Hi

I started with the recommendation in APress "beginnng hibernate"

The example worked fine and all the controllers would work so long as the dao was injected directly into the controller.

But then I tried to put a "service" layer between the controller and the dao.

So I was now injecting the "service" into the controller.
And injecting the dao into the service.

I then got this error

Error creating bean with name 'detailsService' defined in ServletContext resource [/WEB-INF/details-servlet.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [package.MyDao$$EnhancerByCGLIB$$73073c23] torequired type [package.MyDao] for property 'myDao'; nested exception is java.lang.IllegalArgumentException: Original must not be null


Eventually I discovered I could overcome this error by changing the type ofthe myDao in the service class to just
"Object" and it worked!

Any thoughts on why the problem
1. would happen and
2. if this is an acceptable workaround.

Thanks in advance

Here is the details-servlet.xml:


Here is the database-data.xml:
The dao is defined as follows
<bean id="myDao" parent="daoTxTemplate">
<property name="target">
<bean class="package.myDao">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</property>
</bean>


<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<!-- Data Source to use. -->
<property name="dataSource" ref="dataSource" />

<property name="annotatedClasses">
<list>
<value>myDto</value>
</list>
</property>


<!-- Hibernate Properties -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.IngresDialect</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.jdbc.batch_size">20</prop>
<!--<prop key="hibernate.current_session_context_class">thread</prop>
--></props>
</property>

</bean>

<bean name="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>


<bean id="daoTxTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>




<bean id="myDao" parent="daoTxTemplate">
<property name="target">
<bean class="package.myDao">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</property>
</bean>
 
A

Aeris

(e-mail address removed) wrote:

I don't see any «detailsService» in your Spring configuration. So…

In your config file, your real DAO is a proxy of your class, managed by
Spring through CGLIB, so your DAO type in your service must not be MyDAO
directly but a dynamic type build at runtime by CGLIB, which is impossible
to manage with Spring (all type must be known at compile time, not at
runtime).

If you want 3tiers architecture (DOM/DAO/Service), you have to handle
«native» class (not proxified):

public class MyDAO {}
public class MyService {
private MyDAO dao;
public void setDAO(MyDAO dao) { this.dao = dao; }
}

<bean id="myDao" class="MyDAO" />
<bean id="myService" class="MyService">
<property name="dao" ref="myDao" />
</bean>
 
C

comp.lang.java.programmer

(e-mail address removed) wrote:

I don't see any «detailsService» in your Spring configuration. So…

In your config file, your real DAO is a proxy of your class, managed by
Spring through CGLIB, so your DAO type in your service must not be MyDAO
directly but a dynamic type build at runtime by CGLIB, which is impossible
to manage with Spring (all type must be known at compile time, not at
runtime).

If you want 3tiers architecture (DOM/DAO/Service), you have to handle
«native» class (not proxified):

public class MyDAO {}
public class MyService {
   private MyDAO dao;
   public void setDAO(MyDAO dao) { this.dao = dao; }

}

<bean id="myDao" class="MyDAO" />
<bean id="myService" class="MyService">
    <property name="dao" ref="myDao" />
</bean>

That's good and I have no wish to have a proxified class.

But how can I have a POJO DAO like in Apress "beginning hibernate"
that doesn't need to worry about sessions ie just

Session session = this.sessionFactory.getCurrentSession();

and allows rendering to JSP and no need to start or commit
transactions.

I will be using this in a read-only environment and I want to avoid
worrying about connections/sessions/transactions.

Also this code would be used as a template for future java based
reports.

If I have to use HibernateDaoSupport I will, I just thought the above
way was recommended.


Cheers.
 
A

Aeris

comp.lang.java.programmer said:
and allows rendering to JSP and no need to start or commit
transactions.

For JSP, the pattern open-session-in-view with a servlet filter is very
efficient in this case.
http://community.jboss.org/wiki/OpenSessioninView

For pure Java, uses @Transactionnal Spring annotation on your application
layer.
http://static.springsource.org/spring/docs/current/spring-framework-
reference/html/transaction.html#transaction-declarative-annotations

All those ways are generic and reusable.
 
A

Aeris

comp.lang.java.programmer said:
But how can I have a POJO DAO like in Apress "beginning hibernate"
that doesn't need to worry about sessions ie just

Just for note, imo, managing transaction in DAO level is a bad idea.
Transactions must be managed at least on service layer, best on the
application layer.

For exemple, fetch object (1st DAO access) then delete them (2nd access)
must be done in the same transaction, not in 2.

class DAO {
Collection<T> get(…);
void delete(Collection<T> objects);
}
class Service {
void method1(…) {
dao.delete(dao.get(…));
}
}

In case of DAO-transactionnal, real db accesses will be
method1, begin, get, commit, begin, delete, commit
But expected accesses would rather be
begin, method1, get, delete, commit
ie service-transactionnal

In more complex cases, transactions should even be managed in application
layer, because transaction must be arround multiple service accesses and not
per service accesses.
 
L

Lew

comp.lang.java.programmer said:
That's good and I have no wish to have a proxified class.

But how can I have a POJO DAO like in Apress "beginning hibernate"
that doesn't need to worry about sessions ie just

Session session = this.sessionFactory.getCurrentSession();

Don't use 'Session'. Use 'EntityManager'. The 'Session' interface is out of
date, supplanted by JPA.
 
A

Arne Vajhøj

Don't use 'Session'. Use 'EntityManager'. The 'Session' interface is out
of date, supplanted by JPA.

Not really.

Hibernate today has two interfaces - the traditional and JPA.

You can not say that JPA is replacing the traditional - it is
supplementing it.

It is a good argument for using JPA that JPA is a standard and not
tied to Hibernate, but not everyone prioritize that aspect.

Arne
 
L

Lew

Not really.

Hibernate today has two interfaces - the traditional and JPA.

You can not say that JPA is replacing the traditional - it is
supplementing it.

It is a good argument for using JPA that JPA is a standard and not
tied to Hibernate, but not everyone prioritize that aspect.

That is a good argument. There are others, and also times when JPA doesn't apply.

The main reason I prefer the JPA interface isn't that it's standard, it's that
it's easier.

I've used Hibernate itself both ways. While superficially cognate, and rumor
has it that Hibernate's implementation of one uses the other (too lazy to
check, myself), 'EntityManager' works better for me than 'Session'.

Maybe it's just the switch from XML to annotations that's the real reason.
I'm actually not sure why one works better. The idioms for
'EntityManagerFactory' (EMF) and 'EntityManager' (EM), whether manual or
injected, just plug in well with application logic, deployment descriptors and
JNDI to RDBMS configuration. Perhaps it is the standardness that makes it fit
so well in the overall deploy-and-run world, after all.

Object lifetime and size of the managed-data pool (per EM) are quite, er,
manageable with the JPA approach.

I'm not adept enough yet to speak to the managed-vs-unmanaged object
transitions that are useful but rather tricky. A lot of common situations are
covered by simple lightweight DA-layer service objects that carry their own
EMs with them.

It's a different way from monolithic DAOs that are tied to atomic data actions
on a single entity type. If you do that, you run into inefficiency and the
sorts of thing that I hear pejorative about Hibernate. Don't blame a hammer
if you have trouble cutting wood with it.

Instead, create services. Let the services figure out the persistence issues
for you. They can provide services for a particular entity, though often with
only a subset of its possible relationships. They can choreograph multiple
entities, e.g., as an order service for an online operation might.

Though hidden from service consumers, this approach lets you tie the life (and
crowdedness) of an EM to the need for its management capabilities rather
neatly. Monolithic approaches tend to create longer-lived EMs with lots and
lots more to manage and no easy way to reason about their state of management.

That's fine if you want to spend a lot of effort fighting your own
architecture. But good The diamond operator is coming!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top