2015-11-16 2 views
1

У меня есть Java на основе конфигурации, где я определяю базы данных, связанные боб следующим образом:Получения ленивых объектов из JPA2 хранилищ не удается без OpenEntityManagerInViewFilter

@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); 

поэтому не ice is Доступ ленивая собственность, что userConverter хочет превратиться в DTO в getUserByUsername транзакционный метод. Однако, когда это произойдет, то он терпит неудачу с этой ошибкой

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> 

Тем не менее, кажется, что будет неправильным исправить. Я хочу найти правильное решение проблемы.

ответ

0

Проведя несколько часов по этому вопросу, я, наконец, понял это. У меня был класс ApplicationConfig, который определил @ComponentScan, который, в свою очередь, загрузил файл DatabaseConfig. Поэтому, как только я переместил @EnableJpaRepositories("z.y.x") и @EnableTransactionManagement(mode = AdviceMode.PROXY) аннотации на класс ApplicationConfig, он начал нормально работать.