在没有OpenEntityManagerInViewFilter的情况下从JPA2存储库中获取延迟实体失败

时间:2015-11-16 11:14:56

标签: java hibernate jpa-2.1

我有一个基于java的配置,我在其中定义了与数据库相关的bean,如下所示:

@Configuration
@EnableJpaRepositories("z.y.x")
@EnableTransactionManagement(mode = AdviceMode.PROXY)
public class DatabaseConfig {

    @Autowired
    DataSource dataSource;

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
        bean.setDataSource(dataSource);
        bean.setPackagesToScan("z.y.x");
        bean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        bean.setJpaPropertyMap(getJpaProperties());
        return bean;
    }

    private Map<String, Object> getJpaProperties() {
        Map<String, Object> map = new HashMap<>();
        map.put("hibernate.hbm2ddl.auto", "validate");
        map.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
        map.put("hibernate.show_sql", false);
        map.put("hibernate.format_sql", true);
        map.put("hibernate.use_sql_comments", true);
        return map;
    }

    @Bean
    public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }

    @Bean
    public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
        return new NamedParameterJdbcTemplate(dataSource);
    }
}

然后在我的服务中,我从数据库中获取一些数据

@Override
@Transactional
public UserDTO getUserByUsername(String username) {
    User user = userRepo.getUserByUsername(username);
    return userConverter.convert(user);
}

用户对象具有这种结构

@Entity
@Table(name = "USERS", uniqueConstraints =
@UniqueConstraint(columnNames = {"username"}))
public class User implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private int id;

    private String username;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = {CascadeType.ALL}, orphanRemoval = true)
    private Set<AccessLevel> accesses = new HashSet<>(0);

注意它有访问懒惰属性,userConverter希望在getUserByUsername事务方法中变成DTO。但是,当它发生时,它会因此错误而失败

  

org.hibernate.LazyInitializationException:懒得初始化   一组角色:repositories.models.User.accesses,不能   初始化代理 - 没有会话

我不知道为什么会这样。

这可以通过在web.xml中添加以下过滤器来解决:

<filter>
    <filter-name>oemInViewFilter</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
    <init-param>
        <param-name>entityManagerFactoryBeanName</param-name>
        <param-value>entityManagerFactory</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>oemInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

然而,这似乎是一个错误的解决方案。我想找到解决问题的正确方法。

1 个答案:

答案 0 :(得分:0)

在这个问题上花了几个小时后,我终于明白了。我有一个ApplicationConfig类,它定义了@ComponentScan,后来又加载了DatabaseConfig文件。因此,一旦我将@EnableJpaRepositories("z.y.x")@EnableTransactionManagement(mode = AdviceMode.PROXY)注释移至ApplicationConfig类,它就开始正常工作。