hibernate lazy loading not working with spring boot=>未能延迟初始化角色集合无法初始化代理-无会话

mefy6pfw  于 2021-07-13  发布在  Java
关注(0)|答案(1)|浏览(330)

我正在尝试通过使用fetchtype.lazy为我们的基金实体实现延迟加载,该基金实体与fundalternateid实体具有一对多关系
尝试访问基金终结点时,出现以下错误:
原因:org.hibernate.lazyinitializationexception:未能延迟初始化角色集合:com.example.model.fund.fundalternateids,无法初始化代理-无会话
jsonmappingexception:未能延迟初始化角色的集合:com.example.model.model.fundalternateids,无法初始化代理-无会话(通过引用链:java.util.collections$unmodifiablerandomaccesslist[0]->com.example.model.model.fundalternateids[“fundalternateids”]);在com.fasterxml.jackson.databind.jsonmappingexception.wrapwithpath(jsonmappingexception)上。java:397) ;
以下是我的项目文件:
基金实体

@Entity(name="fund")
@Table(name="mv_fund_info")
@Getter
@Setter
public class Fund implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "fund_port_id")
    private String fundPortId;

    @Column(name = "fund_full_name")
    private String fundFullName;

    @Column(name = "fund_short_name")
    private String fundShortName;

    @OneToMany(
            mappedBy = "associatedFund",
            fetch = FetchType.LAZY
    )
    @JsonManagedReference
    private List<FundAlternateId> fundAlternateIds;
}

fundalternateid类

@Entity(name="fundAlternateId")
@Table(name="mv_fund_alternate_id")
@Getter
@Setter
public class FundAlternateId implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @JsonIgnore
    @Column(name="alternate_id_ins_id")
    private Long alternateIdInsId;

    @Column(name="alternate_id_value")
    @Text
    private String alternateIdValue;

    @Column(name="alternate_id_type")
    @Text
    private String alternateIdType;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="fund_port_id")
    @JsonBackReference
    private Fund associatedFund;
}

休息控制器

@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response getPublicFundAttributes() {
  List<Fund> publicFunds = fundService.getAllPublicFunds(offset,limit, sortBy);
  return Response.status(Status.OK).type(MediaType.APPLICATION_JSON).entity(publicFunds).build();
}

基金服务

@Service
@Transactional("myTransactionManager")
public class FundServiceImpl implements FundService {

    @Autowired
    FundDao fundDao;

    @Override
    public List<Fund> getAllPublicFunds(Integer pageNo, Integer pageSize, String sortBy) {
        List<Fund> fundList = fundDao.getAllPublicFunds(pageNo, pageSize, sortBy);
        return fundList;
    }
}

本道
@名为(“funddao”)的公共类funddaoimpl实现funddao{

@Autowired
@Qualifier("fundRepository")
FundRepository fundRepository;

@Override
public List<Fund> getAllPublicFunds() {
    List<Fund> pagedResult = fundRepository.findAll();
    return pagedResult;
}

}
基金存储库

@Repository("fundRepository")
public interface FundRepository extends PagingAndSortingRepository<Fund, String> {}

配置类

@Configuration
@EnableJpaRepositories(
        basePackages = {"com.example.repository"},
        entityManagerFactoryRef = "myEntityManagerFactory",
        transactionManagerRef = "myTransactionManager"
)
@EnableTransactionManagement
public class ApplicationDatabaseConfiguration {

    @Bean(name = "myEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean getEntityManagerFactory(@Qualifier("postGresDataSource") HikariDataSource dataSource) {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource);
        em.setPackagesToScan(new String[] { "com.example.model"});
        em.setJpaVendorAdapter(hibernateJpaVendorAdapter());
        em.setJpaPropertyMap(buildJpaPropertyMap());

        return em;
    }

    @Bean
    public HibernateJpaVendorAdapter hibernateJpaVendorAdapter() {

        HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        adapter.setDatabasePlatform("org.hibernate.dialect.PostgreSQL9Dialect");
        adapter.setShowSql(false);
        adapter.setGenerateDdl(false);

        return adapter;
    }

    @Bean(name = "postGresDataSource")
    public HikariDataSource getDataSource() {
        HikariDataSource dataSource  = new HikariDataSource();

        try {
            dataSource.setDriverClassName("org.postgresql.Driver");
        } catch (Exception e) {
            logger.error("ApplicationDatabaseConfiguration.getDataSource() has issue to get data source:", e);
        }

        dataSource.setDriverClassName("org.postgresql.Driver");
        dataSource.setJdbcUrl(jdbcUrl);
        dataSource.setUsername(userId);
        dataSource.setPassword(password);
        dataSource.setAutoCommit(true);
        dataSource.setMaximumPoolSize(25);
        dataSource.setMaxLifetime(300000);
        dataSource.setIdleTimeout(30000);

        return dataSource;
    }

    @Bean(name = "sleeveTransactionManager")
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager tm = new JpaTransactionManager();
        tm.setEntityManagerFactory(getEntityManagerFactory(getDataSource()).getObject());
        tm.setDataSource(getDataSource());

        return tm;
    }
}
hgb9j2n6

hgb9j2n61#

正如@code\u mechanic在注解中所建议的,有两种方法可以解决此问题:
初始化中的所有惰性引用 Transaction (您的服务层)
将中的所有延迟引用设置为null Controller 在返回api响应之前。
我开发了两个实用方法,您可以使用它们动态地检查惰性对象是否已初始化。您可以在控制器层中使用以下方法:

/**
 * Was collection initialized.
 *
 * @param c the c
 * @return true, if successful
 */
public static boolean wasCollectionInitialized(Object c) {
    if (!(c instanceof PersistentCollection)) {
        return true;
    }

    PersistentCollection pc = (PersistentCollection) c;
    return pc.wasInitialized();
}

/**
 * Was object initialized.
 *
 * @param c the c
 * @return true, if successful
 */
public static boolean wasObjectInitialized(Object c) {
    if (!(c instanceof HibernateProxy)) {
        return true;
    }

    HibernateProxy pc = (HibernateProxy) c;
    return !pc.getHibernateLazyInitializer().isUninitialized();
}

相关问题