Announcement Announcement Module
Collapse
No announcement yet.
How Common to Spring Manage Beans Created By Hibernate? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #46
    Everything appears to be being wired up correctly for me using the three new classes from the sandbox with 1.1.1, except that my Hibernate persisted object does not get its setApplicationContext method called after being rehydrated (all the other properties are correctly wired).
    It won't call setApplicationContext() with the autowiring approach. Autowiring does not register the object with the application context as a prototype, it merely does Dependency Injection based on resolving properties. This is consistent with the BeanFactory semantics on autowiring existing objects with dependencies from a factory.

    If you want the ApplicationContextAware and other lifecycle interfaces to be invoked, you should use full factory management of your beans by defining them as prototypes.

    Guess I should update the Javadoc to indicate this.

    Comment


    • #47
      thanks

      Originally posted by Rod Johnson
      If you want the ApplicationContextAware and other lifecycle interfaces to be invoked, you should use full factory management of your beans by defining them as prototypes.
      Ah, that makes sense now. After changing autowire to 0 and defining the prototypes in managedClassNamesToPrototypeNames, it works great.

      Thanks...

      Comment


      • #48
        I've updated the Javadoc. Thanks for bringing this to my attention.

        Comment


        • #49
          There is a slight inconsistency with how Hibernate might wire a bean's ID and how this new interceptor is doing it.

          The interceptor will use BeanWrapper.setPropertyValue to set the ID. This will not work if the bean has only a getter for the ID (and only field access for the ID). If no setter exists, then a NotWritablePropertyException is thrown.

          Hibernate, on the other hand, is able to use field access to set properties of a bean.

          I wonder if the interceptor should first try setPropertyValue, and if it fails, to try setting the field directly? We removed our setId() method to make it more clear users aren't able to set this. We'll set it to private for now, but if we're able to set the ID via its field, that would be even better.

          Any reason not to?

          Comment


          • #50
            Actually, turns out I have to create a public setId() to get it to work with setPropertyValue.

            I'd like to be able to work with private setters, or even better yet, just accessing the field. If this is a good idea, I'll post the patch.

            Comment


            • #51
              I just performed some basic tests to see if there is a speed difference between autowiring and the prototype. For my tests, it was 10.6% faster to use the prototype map than to use autowiring.

              Just a note.

              Comment


              • #52
                ApplicationContext Config

                I am new to Spring, could some one please post the xml config settings for getting the SpringInterceptor up and running?

                thanks in advance.

                Comment


                • #53
                  Re: ApplicationContext Config

                  Originally posted by sfwalter
                  I am new to Spring, could some one please post the xml config settings for getting the SpringInterceptor up and running?

                  thanks in advance.
                  Something like the following is what I had, though your needs might be different (might not want lazy-init set to true, might not use JTA, etc):

                  Code:
                  <bean id="dependencyInjectionInterceptor" class="org.springframework.orm.hibernate.support.DependencyInjectionInterceptorFactoryBean">
                      <property name="sessionFactoryName">
                          <value>sessionFactory</value>
                      </property>
                      <property name="defaultAutowireMode">
                          <value>0</value>
                      </property>
                      <property name="managedClassNamesToPrototypeNames">
                          <props>
                              <prop key="com.thatone.archie.engine.task.MoveTask">moveTask</prop>
                              <prop key="com.thatone.archie.engine.task.DeleteTask">deleteTask</prop>
                              <prop key="com.thatone.archie.engine.task.CopyTask">copyTask</prop>
                              <prop key="com.thatone.archie.persistence.ArchieDataSourceImpl">archieDataSource</prop>
                              <prop key="com.thatone.archie.engine.job.QuartzJobImpl">archieJob</prop>
                          </props>
                      </property>
                  </bean>
                  <bean id="sessionFactory"
                      class="org.springframework.orm.hibernate.LocalSessionFactoryBean" lazy-init="true">
                      <property name="dataSource">
                          <ref local="wrappedAppDataSource"/>
                      </property>
                      <property name="mappingResources">
                          <list>
                              <value>hbm/ApplicationModel.hbm.xml</value>
                              <value>hbm/ArchieWorkflow.hbm.xml</value>
                              <value>hbm/Datasource.hbm.xml</value>
                              <value>hbm/Job.hbm.xml</value>
                              <value>hbm/Signature.hbm.xml</value>
                              <value>hbm/Task.hbm.xml</value>
                              <value>hbm/Context.hbm.xml</value>
                              <value>hbm/workflow/HibernateCurrentStep.hbm.xml</value>
                              <value>hbm/workflow/HibernateHistoryStep.hbm.xml</value>
                              <value>hbm/workflow/HibernateWorkflowEntry.hbm.xml</value>
                              <value>hbm/workflow/PropertySetItemImpl.hbm.xml</value>
                          </list>
                      </property>
                      <property name="hibernateProperties">
                          <ref local="hibernateProperties"/>
                      </property>
                      <property name="entityInterceptor">
                          <ref local="dependencyInjectionInterceptor"/>
                      </property>
                      <property name="jtaTransactionManager">
                          <ref local="jotm"/>
                      </property>
                  </bean>
                  I've omitted non-essential bean definitions, but those are the crucial ones.

                  hth,

                  calvin

                  Comment


                  • #54
                    Re: How Common to Spring Manage Beans Created By Hibernate?

                    Originally posted by sethladd
                    Hello,

                    We've heard time and time again to "put business logic inside your business objects". Most of the time, full business logic requires dependencies to be injected in my business object. The business objects themselves (Business, Account, etc) are managed by Hibernate. Their dependencies are/should be managed by Spring.

                    How common is this? If my business object is something that comes from the database, but requires external dependencies, then Spring must create and wire up my object.

                    This seems fair and good, but I haven't seen many examples of this usage. It makes me wonder if my business domain objects (those that come from the database) should ever rely on external dependencies.

                    My gut says yes: keep business logic in business object. Note: this does not mean DAO type actions.

                    Of course, I could keep the business objects free from external dependencies, but then their ability to do work is greatly lessened.

                    Thoughts? Comments? War stories?

                    Thanks very much!
                    Seth
                    If you use dependency injection (Spring beans) how would you like to solve the issue that a persistent object lives only as long as the transaction lives?
                    If you create a Spring bean and it references a persistent object you'll get an exception if the next transaction tries to access the referenced object. This is because the object is only valid for the transaction it was loaded. After commit/rollback the association with the DB is lost.

                    Comment


                    • #55
                      I think you are talking about how once you close the session, you aren't able to traverse lazy loaded relationships. That is true. It's a good practice to load up all relationships needed for the use case before the session is closed. Then, when that object "goes out into the wild", you have loaded everything.

                      We've been DI'ing our Hibernate objects for some time with great success. I think it was a key missing ingredient for a true OO system.

                      Did I misinterpret the meaning of your post?

                      Comment


                      • #56
                        Current approach

                        I see that the lates code in the sandbox (at least that I could find) related to this has not been updated in over a year and never made it into the actual framework. Currently, using Hibernate 3 without Hibernate 2 in the classpath breaks the sandbox code, as it relies on Hibernate 2 Interceptor (net.sf) syntax. Not intending to re-open old wounds, but what's the current thinking on how
                        best to address this type of functionality?

                        thanks,
                        Zach

                        Comment


                        • #57
                          My understanding is, @Configure+AspectJ is the preferred way to achieve this in Spring 2.0.

                          Comment


                          • #58
                            Thanks for the follow-up. Since my post, I noticed that approach referenced here:

                            http://www.springframework.org/docs/reference/aop.html
                            in section 6.8.1

                            As well as some approaches here:
                            http://debasishg.blogspot.com/2006/0...ur-domain.html

                            While I like aspectj, on large development teams it isn't always possible to force aspectj weaving on everyone. In addition, the documentation in 6.8.1 does reference DependencyInjectionInterceptorFactoryBean, but when I look at both the svn and cvs repository here, I don't see the bean.

                            I'm going to investigate further the blog post referenced above to see if I can figure out a decent, non-aspectj solution to this problem, outside of apparently DependencyInjectionInterceptorFactoryBean, unless I can find (or am told about) an up to date version somewhere.

                            thanks,
                            Zach

                            Comment

                            Working...
                            X