简体   繁体   中英

Hibernate one to many bidirectional association not loading with Spring Data

I have a bi-directional mapping as below

@Entity
@Table(name = "Stock")
public class StockEntity implements Serializable {


    private String planNum;

    private Set<StockOptionEntity> options = new HashSet<StockOptionEntity>(0);



    @OneToMany(fetch = FetchType.EAGER, mappedBy="stock")
    public Set<StockOptionEntity> getOptions() {
        return Options;
    }

    public void setOptions(Set<StockOptionEntity> Options) {
        this.Options = Options;
    }
}

Then I have another mapping as below..

@Entity
@Table(name = "StockOption")
@IdClass(StockOptionEntityPK.class)
public class StockOptionEntity implements Serializable {



    private StockEntity stock;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "PlanNum", insertable = false, updatable = false)    
    public StockEntity getStock() {
        return Stock;
    }

    public void setStock(StockEntity Stock) {
        this.Stock = Stock;
    }
}

I then have the Spring Beans declared as below for Session, Entity & Transaction manager

@Bean
public DataSource msSqlDataSource() {
    SQLServerConnectionPoolDataSource dataSource = new SQLServerConnectionPoolDataSource();
    ...........
    return dataSource;

}
@Bean
@DependsOn({ "msSqlDataSource"})    
public LocalSessionFactoryBean sessionFactory() {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    try {
        sessionFactory.setDataSource(msSqlDataSource());
    } catch (Exception e) {
        log.error("Failed to attach dataSource object to SessionFactory bean. "
                + "Exception: " + e.getMessage());
    }
    sessionFactory
            .setPackagesToScan("com.firstx.db.entity.*");
    sessionFactory.setHibernateProperties(hibernateProperties());

    return sessionFactory;
}
@Bean
@DependsOn({ "sessionFactory","msSqlDataSource"})
public EntityManagerFactory entityManagerFactory() {

    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setGenerateDdl(true);

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setPackagesToScan("com.firstx.db.entity.*");
    try {
        factory.setDataSource(msSqlDataSource());
    } catch (Exception e) {
        log.error("Failed to attach dataSource object to EntityManagerFactor bean. "
                + "Exception: " + e.getMessage());
    }
    factory.afterPropertiesSet();

    return factory.getObject();
}
  @Bean
   public PlatformTransactionManager transactionManager(){
      JpaTransactionManager transactionManager = new JpaTransactionManager();
      transactionManager.setEntityManagerFactory(
              entityManagerFactory() );
      return transactionManager;
   }

And then lastly, Im using Spring Data repository - repository.findOne(...) method to extract my Stock object along with StockOptions.

In this case, im not able to retrieve the collection of stock options. The collection is empty.

I tried below ways (Keeping the Spring beans as constant),

  1. Converted the relation as unidrectional (by removing mappedBy and related stuff).
  2. Removed the initialization of Set.
  3. Removed the ID class for StockOption

Both the above options didnt work.

In the debug, I see that the StockOptions are successfully retrieved and loaded on to the session cache. But, Im not able to figure out why it isnt being actually loaded back to the parent object.

Below is the debug...

1853270 [http-nio-8080-exec-10] TRACE o.h.e.i.DefaultInitializeCollectionEventListener - Initializing collection [com.firstx.db.entity.base.StockEntity.options#d97]
1853270 [http-nio-8080-exec-10] TRACE o.h.e.i.DefaultInitializeCollectionEventListener - Checking second-level cache
1853270 [http-nio-8080-exec-10] TRACE o.h.e.i.DefaultInitializeCollectionEventListener - Collection not cached
1853271 [http-nio-8080-exec-10] DEBUG o.h.l.c.p.AbstractLoadPlanBasedCollectionInitializer - Loading collection: [com.firstx.db.entity.base.StockEntity.options#d97]
1853271 [http-nio-8080-exec-10] DEBUG org.hibernate.SQL - select options0_.PlanNum as PlanNum1_11_0_, options0_.PlanNum as PlanNum1_13_0_, options0_.OptionCode as Optio2_13_0_, options0_.PlanNum as PlanNum1_13_1_ ......... from StockOption options0_ where options0_.PlanNum=?
1853271 [http-nio-8080-exec-10] TRACE o.h.e.j.i.JdbcCoordinatorImpl - Registering statement [SQLServerPreparedStatement:13]
1853271 [http-nio-8080-exec-10] TRACE o.h.e.j.i.JdbcCoordinatorImpl - Registering last query statement [SQLServerPreparedStatement:13]
1853271 [http-nio-8080-exec-10] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [d97]
1853271 [http-nio-8080-exec-10] TRACE o.h.l.p.e.i.AbstractLoadPlanBasedLoader - Bound [2] parameters total
1853305 [http-nio-8080-exec-10] TRACE o.h.e.j.i.JdbcCoordinatorImpl - Registering result set [SQLServerResultSet:68]
1854044 [http-nio-8080-exec-10] DEBUG o.h.l.p.e.p.i.ResultSetProcessorImpl - Preparing collection intializer : [com.firstx.db.entity.base.StockEntity.options#d97]
1854044 [http-nio-8080-exec-10] TRACE o.h.e.loading.internal.LoadContexts - Constructing collection load context for result set [SQLServerResultSet:68]
1854773 [http-nio-8080-exec-10] TRACE o.h.e.l.i.CollectionLoadContext - Starting attempt to find loading collection [[com.firstx.db.entity.base.StockEntity.options#d97]]
1854773 [http-nio-8080-exec-10] TRACE o.h.e.loading.internal.LoadContexts - Attempting to locate loading collection entry [CollectionKey[com.firstx.db.entity.base.StockEntity.options#d97]] in any result-set context
1854774 [http-nio-8080-exec-10] TRACE o.h.e.loading.internal.LoadContexts - Collection [CollectionKey[com.firstx.db.entity.base.StockEntity.options#d97]] not located in load context
1854774 [http-nio-8080-exec-10] TRACE o.h.e.l.i.CollectionLoadContext - Collection not yet initialized; initializing
1854774 [http-nio-8080-exec-10] TRACE o.h.l.p.e.p.i.ResultSetProcessorImpl - Processing result set
1854774 [http-nio-8080-exec-10] DEBUG o.h.l.p.e.p.i.ResultSetProcessorImpl - Starting ResultSet row #0
1854774 [http-nio-8080-exec-10] TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([PlanNum1_13_1_] : [VARCHAR]) - [D97]
1854774 [http-nio-8080-exec-10] TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([Optio2_13_1_] : [VARCHAR]) - [03]
1854775 [http-nio-8080-exec-10] TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([PlanNum1_11_0_] : [VARCHAR]) - [D97]
1854775 [http-nio-8080-exec-10] DEBUG o.h.l.p.e.p.i.CollectionReferenceInitializerImpl - Found row of collection: [com.firstx.db.entity.base.StockEntity.options#D97]
1855453 [http-nio-8080-exec-10] TRACE o.h.e.l.i.CollectionLoadContext - Starting attempt to find loading collection [[com.firstx.db.entity.base.StockEntity.options#D97]]
1855454 [http-nio-8080-exec-10] TRACE o.h.e.loading.internal.LoadContexts - Attempting to locate loading collection entry [CollectionKey[com.firstx.db.entity.base.StockEntity.options#D97]] in any result-set context
1855454 [http-nio-8080-exec-10] TRACE o.h.e.loading.internal.LoadContexts - Collection [CollectionKey[com.firstx.db.entity.base.StockEntity.options#D97]] not located in load context
1855454 [http-nio-8080-exec-10] TRACE o.h.e.l.i.CollectionLoadContext - Collection already initialized; ignoring
1856195 [http-nio-8080-exec-10] DEBUG o.h.l.p.e.p.i.ResultSetProcessorImpl - Starting ResultSet row #1
1856196 [http-nio-8080-exec-10] TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([PlanNum1_13_1_] : [VARCHAR]) - [D97]
1856196 [http-nio-8080-exec-10] TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([Optio2_13_1_] : [VARCHAR]) - [18]
1856196 [http-nio-8080-exec-10] TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([PlanNum1_11_0_] : [VARCHAR]) - [D97]
1856196 [http-nio-8080-exec-10] DEBUG o.h.l.p.e.p.i.CollectionReferenceInitializerImpl - Found row of collection: [com.firstx.db.entity.base.StockEntity.options#D97]
1856819 [http-nio-8080-exec-10] TRACE o.h.e.l.i.CollectionLoadContext - Starting attempt to find loading collection [[com.firstx.db.entity.base.StockEntity.options#D97]]
1856820 [http-nio-8080-exec-10] TRACE o.h.e.loading.internal.LoadContexts - Attempting to locate loading collection entry [CollectionKey[com.firstx.db.entity.base.StockEntity.options#D97]] in any result-set context
1856820 [http-nio-8080-exec-10] TRACE o.h.e.loading.internal.LoadContexts - Collection [CollectionKey[com.firstx.db.entity.base.StockEntity.options#D97]] not located in load context
1856820 [http-nio-8080-exec-10] TRACE o.h.e.l.i.CollectionLoadContext - Collection already initialized; ignoring
1857454 [http-nio-8080-exec-10] DEBUG o.h.l.p.e.p.i.ResultSetProcessorImpl - Starting ResultSet row #2
1857454 [http-nio-8080-exec-10] TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([PlanNum1_13_1_] : [VARCHAR]) - [D97]
1857454 [http-nio-8080-exec-10] TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([Optio2_13_1_] : [VARCHAR]) - [42]
1857455 [http-nio-8080-exec-10] TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([PlanNum1_11_0_] : [VARCHAR]) - [D97]
1857455 [http-nio-8080-exec-10] DEBUG o.h.l.p.e.p.i.CollectionReferenceInitializerImpl - Found row of collection: [com.firstx.db.entity.base.StockEntity.options#D97]
1858028 [http-nio-8080-exec-10] TRACE o.h.e.l.i.CollectionLoadContext - Starting attempt to find loading collection [[com.firstx.db.entity.base.StockEntity.options#D97]]
1858028 [http-nio-8080-exec-10] TRACE o.h.e.loading.internal.LoadContexts - Attempting to locate loading collection entry [CollectionKey[com.firstx.db.entity.base.StockEntity.options#D97]] in any result-set context
1858028 [http-nio-8080-exec-10] TRACE o.h.e.loading.internal.LoadContexts - Collection [CollectionKey[com.firstx.db.entity.base.StockEntity.options#D97]] not located in load context
1858028 [http-nio-8080-exec-10] TRACE o.h.e.l.i.CollectionLoadContext - Collection already initialized; ignoring
1858628 [http-nio-8080-exec-10] TRACE o.h.l.p.e.p.i.ResultSetProcessorImpl - Done processing result set (3 rows)
1858628 [http-nio-8080-exec-10] TRACE o.h.l.p.e.p.i.AbstractRowReader - Total objects hydrated: 0
1859193 [http-nio-8080-exec-10] TRACE o.h.e.loading.internal.LoadContexts - Attempting to locate loading collection entry [CollectionKey[com.firstx.db.entity.base.StockEntity.options#d97]] in any result-set context
1859193 [http-nio-8080-exec-10] TRACE o.h.e.loading.internal.LoadContexts - Collection [CollectionKey[com.firstx.db.entity.base.StockEntity.options#d97]] located in load context
1861703 [http-nio-8080-exec-10] TRACE o.h.e.l.i.CollectionLoadContext - Removing collection load entry [org.hibernate.engine.loading.internal.LoadingCollectionEntry<rs=SQLServerResultSet:68, coll=[com.firstx.db.entity.base.StockEntity.options#d97]>@8edfd0]
1863159 [http-nio-8080-exec-10] DEBUG o.h.e.l.i.CollectionLoadContext - 1 collections were found in result set for role: com.firstx.db.entity.base.StockEntity.options
1863159 [http-nio-8080-exec-10] TRACE o.h.e.l.i.CollectionLoadContext - Ending loading collection [org.hibernate.engine.loading.internal.LoadingCollectionEntry<rs=SQLServerResultSet:68, coll=[com.firstx.db.entity.base.StockEntity.options#d97]>@8edfd0]
1864512 [http-nio-8080-exec-10] DEBUG o.h.e.l.i.CollectionLoadContext - Collection fully initialized: [com.firstx.db.entity.base.StockEntity.options#d97]
1865190 [http-nio-8080-exec-10] DEBUG o.h.e.l.i.CollectionLoadContext - 1 collections initialized for role: com.firstx.db.entity.base.StockEntity.options
1865190 [http-nio-8080-exec-10] TRACE o.h.e.j.i.JdbcCoordinatorImpl - Releasing result set [SQLServerResultSet:68]
1865190 [http-nio-8080-exec-10] TRACE o.h.e.j.i.JdbcCoordinatorImpl - Closing result set [SQLServerResultSet:68]
1865190 [http-nio-8080-exec-10] TRACE o.h.e.j.i.JdbcCoordinatorImpl - Releasing statement [SQLServerPreparedStatement:13]
1865190 [http-nio-8080-exec-10] TRACE o.h.e.j.i.JdbcCoordinatorImpl - Closing prepared statement [SQLServerPreparedStatement:13]
1865211 [http-nio-8080-exec-10] TRACE o.h.e.j.i.JdbcCoordinatorImpl - Starting after statement execution processing [ON_CLOSE]
1865979 [http-nio-8080-exec-10] DEBUG o.h.l.c.p.AbstractLoadPlanBasedCollectionInitializer - Done loading collection
1865979 [http-nio-8080-exec-10] TRACE o.h.e.i.DefaultInitializeCollectionEventListener - Collection initialized
1866720 [http-nio-8080-exec-10] DEBUG o.h.l.e.p.AbstractLoadPlanBasedEntityLoader - Done entity load : com.firstx.db.entity.base.StockEntity#d97
1866720 [http-nio-8080-exec-10] TRACE org.hibernate.internal.SessionImpl - Setting cache mode to: NORMAL
1866720 [http-nio-8080-exec-10] DEBUG o.h.e.t.spi.AbstractTransactionImpl - committing
1866720 [http-nio-8080-exec-10] TRACE org.hibernate.internal.SessionImpl - before transaction completion
1866740 [http-nio-8080-exec-10] DEBUG o.h.e.t.i.jdbc.JdbcTransaction - committed JDBC Connection
1866740 [http-nio-8080-exec-10] DEBUG o.h.e.t.i.jdbc.JdbcTransaction - re-enabling autocommit
1866763 [http-nio-8080-exec-10] TRACE o.h.e.t.i.TransactionCoordinatorImpl - after transaction completion
1866763 [http-nio-8080-exec-10] TRACE org.hibernate.internal.SessionImpl - after transaction completion
1866763 [http-nio-8080-exec-10] TRACE org.hibernate.internal.SessionImpl - Setting flush mode to: AUTO
1866763 [http-nio-8080-exec-10] TRACE org.hibernate.internal.SessionImpl - Closing session
1866764 [http-nio-8080-exec-10] TRACE o.h.e.j.i.JdbcCoordinatorImpl - Closing JDBC container [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl@6dc5a3df]
1866764 [http-nio-8080-exec-10] TRACE o.h.e.j.i.LogicalConnectionImpl - Closing logical connection
1866764 [http-nio-8080-exec-10] DEBUG o.h.e.j.i.LogicalConnectionImpl - Releasing JDBC connection
1866764 [http-nio-8080-exec-10] DEBUG o.h.e.j.i.LogicalConnectionImpl - Released JDBC connection

Also, I didnt enable any caching options.

As you can see above, the stockoption collection is being fetched, but isn't being plugged into the stock object.


UPDATE

The capitalized stock and option in my original posting was a find and replace mistake.. Sorry about that..

I wrote a simple class which bypasses spring data and the result is that it worked! The entity got loaded without any issue.

I think im doing something wrong with Spring data configuration (may be). But not sure.

Below is the simple (regular hibernate DAO style) that works with the same mapping:

@Repository
public class NewStock {

    @Autowired
    private SessionFactory  sessionFactory;

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public StockEntity retrieveStock(String planNum) {

        Session session = sessionFactory.openSession();
        session.beginTransaction();
        List<StockEntity> stockList = session
                                .createQuery("from StockEntity where planNum = '" +
                                        planNum+ "'")
                                        .list();
        session.close();


        return stockList.get(0);

    }

}

Please help in figuring out the root cause.

Please try change

 private StockEntity Stock;

into

private StockEntity stock;

You have to follow Java bean naming conventions when you declare fields and corresponding getter and setter methods.

In StockEntity.java class, the property Options should be options , it should start with small letter.

Same applies to your other entity - StockOptionEntity.java class the property Stock should be stock .

Now coming to the issue, as per logs it has below message:

1854774 [http-nio-8080-exec-10] TRACE o.h.e.loading.internal.LoadContexts - 
Collection [CollectionKey[com.firstx.db.entity.base.StockEntity.options#d97]] not 
located in load context

This message says that hibernate is not able to find a property called options inside StockEntity class. So even when hibernate got the record for StockOptionEntity as it did not find the property it just ignored it.

To fix the issue just follow the Java bean naming conventions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM