java - 如果没有 OpenEntityManagerInViewFilter,从 JPA2 存储库获取惰性实体失败

标签 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);

所以请注意,它具有accesses惰性属性,userConverter想要在getUserByUsername事务方法中转换为DTO。但是,当发生这种情况时,它会失败并出现此错误

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: repositories.models.User.accesses, could not initialize proxy - no Session

我不知道为什么会发生这种情况。

可以通过将以下过滤器添加到 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>

但是,这似乎是一个错误的修复。我想找到解决问题的正确方法。

最佳答案

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

关于java - 如果没有 OpenEntityManagerInViewFilter,从 JPA2 存储库获取惰性实体失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33734044/

相关文章:

java - Android:我应该如何删除 Activity 标题栏?

java - 创建 "good"SecureRandom 的最佳方法是什么?

java - 如何在 Java (Selenium) 设置中使用 Apache POI 多个线程(并行测试用例)同时访问同一个 Excel 文件?

hibernate - JPA - 使用转换器保留 @Temporal LocalDate

entitymanager - JPA 2.1 类型转换器不会对 NULL 值执行

java - "setImageDrawable(Drawable.createFromPath)"从Android网络服务器获取图像

java - 在 Java EE 6 应用程序(数据库/文件系统)中存储大量文件的最佳方式

java - 在 Hibernate 中持久化 LinkedList

java - hibernate ,测试集合是否已完全加载

java - 如何使用 JPA - EntityGraph 只加载实体@Basic 属性的一个子集?