注意:更新#1和更新#2有UserDAOImpl.java,HibernateConfig.java,UserServiceImpl.java
靠近
我知道你需要从Hibernate SessionFactory进行事务处理。 在使用getCurrentSession()获取会话后运行查询在进行事务之前将无法运行。 因此,在@Repository或@Service上使用@Transactional会让spring对其方法的查询应用事务。
为什么entityManager不需要交易,我会深入研究
我需要知道要阅读什么才能理解此异常的含义:
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
我知道有些答案表明@EnableTransactionManagement,有些答案@Transactional,我现在将复制/粘贴解决方案。
我是一个非常基本的用户,我对RDBMS了解不多,我知道如何处理MySQL的基础知识,所以如果你能列出一些要阅读的主题就足够了。
更新#1
我有两个查询,一个工作,另一个给我这个例外,我的任何服务类都没有@Transactional:
UserDAOImpl.java
@Component
public class UserDAOImpl implements UserDAO {
@Autowired
private SessionFactory sessionFactory;
// Works well
@Override
public User findByUsername(String username) {
return (User) sessionFactory.createEntityManager()
.createQuery("from User where username = :username")
.setParameter("username", username)
.getSingleResult();
}
// Gives me the exception
@Override
public User findByUsernameOneColumn(String username, String column) {
return (User) sessionFactory.getCurrentSession()
.createQuery("select :column from User where username = :username")
.setParameter("column", column)
.setParameter("username", username)
.getSingleResult();
}
}
这就是为什么我需要阅读更多而不是复制粘贴,我不应该给-1,我需要学习。
更新#2
HibernateConfig.java
@Configuration
@EnableTransactionManagement
public class HibernateConfig {
@Bean
public DataSource dataSource() {
DataSource dataSource = new DataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/medicallabDB");
dataSource.setUsername("root");
dataSource.setPassword("root");
return dataSource;
}
@Bean
public HibernateTransactionManager transactionManager() {
return new HibernateTransactionManager(sessionFactory().getObject());
}
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean localSessionFactory = new LocalSessionFactoryBean();
try {
localSessionFactory.setDataSource(dataSource());
localSessionFactory.setHibernateProperties(hibernateProperties());
localSessionFactory.setPackagesToScan("medicallab.web.model");
localSessionFactory.afterPropertiesSet();
} catch (Exception e) {
e.printStackTrace();
}
return localSessionFactory;
}
private Properties hibernateProperties() {
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("dialect", "org.hibernate.dialect.MySQLDialect");
hibernateProperties.setProperty("hibernate.show_sql", "true");
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "update");
return hibernateProperties;
}
}
UserServiceImpl.java
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDAO userDAO;
public User findByUsername(String username) {
return userDAO.findByUsername(username);
}
@Override
public User findByUsernameOneColumn(String username, String column) {
User user = null;
try {
user = userDAO.findByUsernameOneColumn(username, column);
System.out.println("user object" + user);
} catch(Exception e) {
e.printStackTrace();
}
return user;
}
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("No such user: " + username);
}
return new User(user);
}
}
答案 0 :(得分:0)
您必须启用事务支持(或@EnableTransactionManagement)并声明transactionManager,它应该通过SessionFactory工作。
您必须将@Transactional添加到您的@Repository
中在@Repository中使用@Transactional Spring可以将事务支持应用到您的存储库中。