spring hibernate injection

Discussion in 'Java' started by eunever32@yahoo.co.uk, Mar 2, 2011.

  1. Guest

    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>
     
    , Mar 2, 2011
    #1
    1. Advertising

  2. Aeris Guest

    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>

    --
    Aeris
     
    Aeris, Mar 2, 2011
    #2
    1. Advertising

  3. On Mar 2, 4:11 pm, Aeris <> wrote:
    > 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>
    >
    > --
    > Aeris


    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.
     
    comp.lang.java.programmer, Mar 2, 2011
    #3
  4. Aeris Guest

    comp.lang.java.programmer wrote:

    > 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.
    --
    Aeris
     
    Aeris, Mar 2, 2011
    #4
  5. Aeris Guest

    comp.lang.java.programmer wrote:

    > 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.


    --
    Aeris
     
    Aeris, Mar 2, 2011
    #5
  6. Lew Guest

    comp.lang.java.programmer wrote:
    > 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.

    --
    Lew
    Honi soit qui mal y pense.
     
    Lew, Mar 2, 2011
    #6
  7. On 02-03-2011 18:46, Lew wrote:
    > comp.lang.java.programmer wrote:
    >> 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.


    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
     
    Arne Vajhøj, Mar 3, 2011
    #7
  8. Lew Guest

    On 03/02/2011 08:52 PM, Arne Vajhøj wrote:
    > On 02-03-2011 18:46, Lew wrote:
    >> comp.lang.java.programmer wrote:
    >>> 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.

    >
    > 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 news: The diamond operator is coming!

    --
    Lew
    Honi soit qui mal y pense.
     
    Lew, Mar 3, 2011
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    0
    Views:
    705
  2. rmn190
    Replies:
    2
    Views:
    2,476
    Arne Vajhøj
    Jan 10, 2008
  3. Alberto Sfolcini

    Spring injection with java annotation?

    Alberto Sfolcini, Apr 24, 2008, in forum: Java
    Replies:
    6
    Views:
    2,335
    Alberto Sfolcini
    Apr 30, 2008
  4. Goldfish
    Replies:
    1
    Views:
    837
    Goldfish
    Nov 6, 2008
  5. Amit Jain
    Replies:
    7
    Views:
    3,394
    Amit Jain
    Apr 27, 2009
Loading...

Share This Page