2013-02-15 8 views
1

Я уже бил головой о стену, пытаясь заставить ее работать. Я создал следующий объект для доступа к данным:Hibernate Transaction Manager - Конфигурация Java

public interface GenericDAO<T, ID extends Serializable> { 
    T findById(ID id); 
    List<T> findAll(); 
    T save(T entity); 
    void update(T entity); 
    void delete(T entity); 
} 

public class GenericHibernateDAO<T, ID extends Serializable> implements GenericDAO<T, ID> { 

    private final Class<T> persistentClass; 
    private final SessionFactory sessionFactory; 

    public GenericHibernateDAO(final SessionFactory sessionFactory) { 
    this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; 
    this.sessionFactory = sessionFactory; 
    } 

    protected Session getSession() { 
    return sessionFactory.getCurrentSession(); 
    } 

    public Class<T> getPersistentClass() { 
    return persistentClass; 
    } 

    @Override 
    public T findById(final ID id) { 
    return (T) getSession().load(getPersistentClass(), id); 
    } 

    @Override @SuppressWarnings("unchecked") 
    public List<T> findAll() { 
    return findByCriteria(); 
    } 

    protected List<T> findByCriteria(final Criterion... criterion) { 
    final Criteria crit = getSession().createCriteria(getPersistentClass()); 
    for (final Criterion c : criterion) { 
     crit.add(c); 
    } 
    return crit.list(); 
    } 

    @Override 
    public T save(final T entity) { 
    getSession().saveOrUpdate(entity); 
    return entity; 
    } 

    @Override 
    public void delete(final T entity) { 
    getSession().delete(entity); 
    } 

    @Override 
    public void update(final T entity) { 
    getSession().saveOrUpdate(entity); 
    } 
} 

@Repository 
public class StockHibernateDAO extends GenericHibernateDAO<Stock, String> implements StockDAO { 

    @Inject 
    public StockHibernateDAO(final SessionFactory sessionFactory) { 
    super(sessionFactory); 
    } 
} 

Я пытающийся установить это с конфигурацией Java, так вот моя конфигурация для установки моего уровня службы:

@Configuration @Profile("hibernate") 
@EnableCaching @EnableTransactionManagement 
@ComponentScan("reference.dao.hibernate") 
public class HibernateServiceConfig implements TransactionManagementConfigurer { 

    @Inject private StockDAO stockDao; //No extra methods, just the base stuff for now 

    @Bean(destroyMethod = "shutdown") 
    public DataSource dataSource() { 
    return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).addScript("classpath:schema.sql").build(); 
    } 

    @Bean 
    public SessionFactory sessionFactory() { 
    return new LocalSessionFactoryBuilder(dataSource()).addAnnotatedClasses(Stock.class) 
    .setProperty("hibernate.show_sql", "true") 
    .setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory") 
    .setProperty("hibernate.cache.use_query_cache", "true") 
    .setProperty("hibernate.cache.use_second_level_cache", "true") 
    .setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect").buildSessionFactory(); 
    } 

    @Override @Bean 
    public PlatformTransactionManager annotationDrivenTransactionManager() { 
    return new HibernateTransactionManager(sessionFactory()); 
    } 

} 

Вот TradingService :

@Service 
public class TradingServiceImpl implements TradingService {  
    @Inject private StockDAO stockDAO; 

    @Override @Transactional 
    @CachePut(value = "stockCache", key = "#stock.name") 
    public Stock addNewStock(final Stock stock) { 
    stockDAO.save(stock); 
    return stock; 
    } 

    @Override @Cacheable(value = "stockCache") 
    public Stock getStock(final String stockName) { 
    return stockDAO.findById(stockName); 
    } 

    @Override @CacheEvict(value = "stockCache", key = "#stock.name") 
    public void removeStock(final Stock stock) { 
    stockDAO.delete(stock); 
    } 

    @Override @CacheEvict(value = "stockCache", key = "#stock.name") 
    public void updateStock(final Stock stock) { 
    stockDAO.update(stock); 
    } 

    @Override 
    public List<Stock> getAll() { 
    return stockDAO.findAll(); 
    } 
} 

Сохранение запаса кажется завершенным, если я добавляю session.flush() в метод сохранения. То, как я понимаю вещи, имея TransactionManager и @Transactional вокруг метода уровня обслуживания, на самом деле должно вызвать этот вызов для меня. Какая конфигурация отсутствует?

+0

Удалить @Inject StockDao и аннотировать этот класс или его реализацию с помощью '@ Repository'. –

ответ

3

Поскольку вы нагнетание Session

@Bean 
    public Session session() { 
    return sessionFactory().openSession(); 
    } 

Spring не может добавить его транзакционный поведение вокруг него. Пусть весна откроет сессию и сделает бизнес.

Вместо инъекции Session введите SessionFactory. В своем DAO сохраните атрибут для SessionFactory и используйте sessionFactory.getCurrentSession() для получения сеанса.

Когда Весна увидит @Transactional, она получит SessionFactory, позвоните по телефону openSession(), начните с нее транзакцию, а затем вызовите ваш метод. Когда ваш метод вернется успешно, он закроет эту транзакцию.

Вы также должны, возможно, @Autowired дао в своем классе обслуживания.

+0

Не будет ли это работать, только если мой DAO будет демаркирован как @Transactional (т. Е. Не getCurrentSession() имеет смысл только в транзакции)? В его нынешнем виде я хочу отметить свой уровень обслуживания транзакциями, а не мой уровень DAO. – Scott

+0

Не имеет значения, кто имеет @Transactional, по умолчанию что-либо внутри вызова метода будет использовать тот же сеанс и транзакцию. –

+0

Тогда что-то еще не совсем верно, так как я получаю следующий стек: org.hibernate.HibernateException: сеанс не найден для текущего потока на org.springframework.orm.hibernate4.SpringSessionContext.currentSession (SpringSessionContext.java:97) at org.hibernate.internal.SessionFactoryImpl.getCurrentSession (SessionFactoryImpl.java:978) at reference.dao.hibernate.GenericHibernateDAO.getSession (GenericHibernateDAO.java:25) – Scott

Смежные вопросы