Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 没有xml文件的Hibernate4配置-sessionFactory为空_Java_Hibernate - Fatal编程技术网

Java 没有xml文件的Hibernate4配置-sessionFactory为空

Java 没有xml文件的Hibernate4配置-sessionFactory为空,java,hibernate,Java,Hibernate,我有一个使用Spring3和Hibernate4的web项目,现在我想在不使用xml文件的情况下测试DAO。为此,我创建了一个类,该类使用应用程序xml文件中包含的数据和一个简单的测试类创建一个LocalSessionFactoryBean 但是,localSessionFactoryBean.getObject()返回的sessionFactory为null。我一直在看一些例子,比如,当我修改它们以在没有Spring的情况下运行时,它们也有同样的问题。你知道吗 这是准备sessionFacto

我有一个使用Spring3和Hibernate4的web项目,现在我想在不使用xml文件的情况下测试DAO。为此,我创建了一个类,该类使用应用程序xml文件中包含的数据和一个简单的测试类创建一个LocalSessionFactoryBean

但是,localSessionFactoryBean.getObject()返回的sessionFactory为null。我一直在看一些例子,比如,当我修改它们以在没有Spring的情况下运行时,它们也有同样的问题。你知道吗

这是准备sessionFactory的代码:

@Configuration
@Transactional
@EnableTransactionManagement
@ComponentScan({ "com.company" })
public class HibernateInitializator {

    public SessionFactory getSessionFactory() {

        Properties hibernateProperties = getHibernateProperties();
        DataSource dataSource = getDatasourceConfiguration();
        LocalSessionFactoryBean localSessionFactoryBean = generateSessionFactoryBean(new String[] { "com.company" },
            dataSource, hibernateProperties);
        SessionFactory sessionFactory = localSessionFactoryBean.getObject();

        HibernateTransactionManager txManager = new HibernateTransactionManager();
        txManager.setSessionFactory(sessionFactory);

        return sessionFactory;
    }

    private DataSource getDatasourceConfiguration() {

        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/dbName");
        dataSource.setUsername("username");
        dataSource.setPassword("password");

        return dataSource;
    }

    private static LocalSessionFactoryBean generateSessionFactoryBean(String[] basePackage, DataSource dataSource,
        Properties hibernateProperties) {

        LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
        localSessionFactoryBean.setDataSource(dataSource);
        localSessionFactoryBean.setPackagesToScan(basePackage);
        localSessionFactoryBean.setHibernateProperties(hibernateProperties);

        return localSessionFactoryBean;
    }

    private static Properties getHibernateProperties() {

        Properties hibernateProperties = new Properties();
        hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
        hibernateProperties.put("hibernate.show_sql", false);
        hibernateProperties.put("hibernate.generate_statistics", false);
        hibernateProperties.put("hibernate.hbm2ddl.auto", "update");
        hibernateProperties.put("hibernate.use_sql_comments", false);

        return hibernateProperties;
    }
}
这是一个使用它的简单测试类:

public class GenericDAOHibernateTest {

    private GenericDAOHibernate dao;

    @BeforeTest
    private void testInitialization() {

        dao = new GenericDAO();
        HibernateInitializator initializator = new HibernateInitializator();
        SessionFactory sessionFactory = initializator.getSessionFactory();
        dao.setSessionFactory(sessionFactory);
    }

    @Test(description = "Checks that returns the user list ")
    public void shouldReturnsUserList() throws SQLException, Exception {

        List<Object[]> openResultSetList = dao.doSomeOperation();
        ...
    }
}
公共类GenericDAOHibernateTest{
私有的genericdao和hibernate-dao;
@试验前
私有无效证明初始化(){
dao=新的GenericDAO();
HibernateInitializator初始化器=新的HibernateInitializator();
SessionFactory SessionFactory=initializator.getSessionFactory();
dao.setSessionFactory(sessionFactory);
}
@测试(description=“返回用户列表的检查”)
public void shouldReturnsUserList()抛出SQLException,Exception{
List openResultSetList=dao.doSomeOperation();
...
}
}
尝试添加此行

localSessionFactoryBean.afterPropertiesSet();
在方法中,设置了
LocalSessionFactoryInstance
的属性之后。您的方法如下所示

private static LocalSessionFactoryBean generateSessionFactoryBean(String[] basePackage, DataSource dataSource,
        Properties hibernateProperties) {
        LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
        localSessionFactoryBean.setDataSource(dataSource);
        localSessionFactoryBean.setPackagesToScan(basePackage);
        localSessionFactoryBean.setHibernateProperties(hibernateProperties);
        // Added the below line
        localSessionFactoryBean.afterPropertiesSet();
        return localSessionFactoryBean;
    }
这可能会为问题增加更多的洞察力

根据文件

public void afterPropertieSet()引发IOException

由BeanFactory在设置所有提供的bean属性(并满足BeanFactoryAware和ApplicationContextAware)后调用。 此方法允许bean实例仅在设置了所有bean属性时执行初始化,并在配置错误时抛出异常


在您的情况下,我认为您需要在代码中手动调用它。

当您使用Spring 3+和Hibernate 4时,我建议您使用一种更好的方法,将所有内容定义为带注释的Spring配置,这样可以顺利地工作

下面是详细的代码,只需复制并粘贴到您的项目中,您就可以
Autowire
SessionFactory在DAO层或任何spring组件中的任何位置:)

然后定义一个
HibernateConfig
,如下所示:

@Configuration
@EnableTransactionManagement
@EnableAspectJAutoProxy
@PropertySource({"classpath:app.properties"})
@ComponentScan(basePackages = "com.mypackages")
public class HibernateConfig {

@Value(Constants.HIBERNATE_DIALECT)
private String hibernateDialect;

@Autowired
private DataSource dataSource;

@Bean(name = "appProperty")
public static PropertySourcesPlaceholderConfigurer appProperty() {
    return new PropertySourcesPlaceholderConfigurer();
}

@Bean(name = "sessionFactory")
public SessionFactory getSessionFactory() throws Exception {

    Properties properties = new Properties();
    properties.put(Constants.HIBERNATE_DIALECT_PROPERTY,
            hibernateDialect);
    properties.put(Constants.HIBERNATE_SHOW_SQL_PROPERTY,
            "false");
    properties
            .put(Constants.HIBERNATE_CURRENT_SESSION_CONTEXT_CLASS_PROPERTY,
                    "thread");
    properties
    .put("dynamic-update","true");
    LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
    factory.setPackagesToScan(new String[] { Constants.DOMAIN_MODEL_PACKAGE });
    factory.setDataSource(dataSource);
    factory.setHibernateProperties(properties);
    factory.afterPropertiesSet();
    return factory.getObject();
}

@Bean(name = "transactionManager")
public HibernateTransactionManager getTransactionManager() throws Exception {
    return new HibernateTransactionManager(getSessionFactory());
}
}
@Configuration
public class JndiConfig {

@Value(Constants.DRIVER_CLASS)
private String driverClassName;
@Value(Constants.DATABASE_URL)
private String databaseURL;
@Value(Constants.USER_NAME)
private String username;
@Value(Constants.PASSWORD)
private String password;
@Value(Constants.MAX_ACTIVE)
private int maxActive;
@Value(Constants.MAX_IDLE)
private int maxIdle;
@Value(Constants.MAX_WAIT)
private long maxWait;
@Value(Constants.MIN_IDLE)
private int minIdle;
@Value(Constants.INITIAL_SIZE)
private int initialSize;
@Value(Constants.TIME_BETWEEN_EVICTION)
private long timeBetweenEvictionRunsMillis;

@Bean(name = "dataSource")
public DataSource dataSource() throws Exception {
    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName(driverClassName);
    dataSource.setUrl(databaseURL);
    dataSource.setUsername(username);
    dataSource.setPassword(password);
    dataSource.setTestOnBorrow(true);
    dataSource.setTestWhileIdle(true);
    dataSource.setValidationQuery("SELECT 1");
    dataSource.setMaxActive(maxActive);
    dataSource.setMaxIdle(maxIdle);
    dataSource.setMaxWait(maxWait);
    dataSource.setMinIdle(minIdle);
    dataSource
            .setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);

    return dataSource;
}
}
然后定义一个
JndiConfig
,如下所示:

@Configuration
@EnableTransactionManagement
@EnableAspectJAutoProxy
@PropertySource({"classpath:app.properties"})
@ComponentScan(basePackages = "com.mypackages")
public class HibernateConfig {

@Value(Constants.HIBERNATE_DIALECT)
private String hibernateDialect;

@Autowired
private DataSource dataSource;

@Bean(name = "appProperty")
public static PropertySourcesPlaceholderConfigurer appProperty() {
    return new PropertySourcesPlaceholderConfigurer();
}

@Bean(name = "sessionFactory")
public SessionFactory getSessionFactory() throws Exception {

    Properties properties = new Properties();
    properties.put(Constants.HIBERNATE_DIALECT_PROPERTY,
            hibernateDialect);
    properties.put(Constants.HIBERNATE_SHOW_SQL_PROPERTY,
            "false");
    properties
            .put(Constants.HIBERNATE_CURRENT_SESSION_CONTEXT_CLASS_PROPERTY,
                    "thread");
    properties
    .put("dynamic-update","true");
    LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
    factory.setPackagesToScan(new String[] { Constants.DOMAIN_MODEL_PACKAGE });
    factory.setDataSource(dataSource);
    factory.setHibernateProperties(properties);
    factory.afterPropertiesSet();
    return factory.getObject();
}

@Bean(name = "transactionManager")
public HibernateTransactionManager getTransactionManager() throws Exception {
    return new HibernateTransactionManager(getSessionFactory());
}
}
@Configuration
public class JndiConfig {

@Value(Constants.DRIVER_CLASS)
private String driverClassName;
@Value(Constants.DATABASE_URL)
private String databaseURL;
@Value(Constants.USER_NAME)
private String username;
@Value(Constants.PASSWORD)
private String password;
@Value(Constants.MAX_ACTIVE)
private int maxActive;
@Value(Constants.MAX_IDLE)
private int maxIdle;
@Value(Constants.MAX_WAIT)
private long maxWait;
@Value(Constants.MIN_IDLE)
private int minIdle;
@Value(Constants.INITIAL_SIZE)
private int initialSize;
@Value(Constants.TIME_BETWEEN_EVICTION)
private long timeBetweenEvictionRunsMillis;

@Bean(name = "dataSource")
public DataSource dataSource() throws Exception {
    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName(driverClassName);
    dataSource.setUrl(databaseURL);
    dataSource.setUsername(username);
    dataSource.setPassword(password);
    dataSource.setTestOnBorrow(true);
    dataSource.setTestWhileIdle(true);
    dataSource.setValidationQuery("SELECT 1");
    dataSource.setMaxActive(maxActive);
    dataSource.setMaxIdle(maxIdle);
    dataSource.setMaxWait(maxWait);
    dataSource.setMinIdle(minIdle);
    dataSource
            .setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);

    return dataSource;
}
}

我问过如何在没有xml文件的情况下做到这一点,@Octopus提出的解决方案解决了我遇到的问题。但是,在修复了该错误后,事务会出现其他错误。。。所以我决定用一种不影响应用程序的不同方式来做

为此,我在/src/test/resources中创建了xml文件的简化版本,删除了许多配置,如c3p0的配置,并对值进行了硬编码,以便在应用程序的属性文件更改时测试不会失败

这是xml文件的内容:

<?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" ...>

    <!-- Spring DataSource -->
    <bean id="testDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/testDatabase" />
        <property name="username" value="testUsername" />
        <property name="password" value="testPassword" />
    </bean>

    <!-- Hibernate 4 SessionFactory -->
    <bean id="testSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" p:dataSource-ref="testDataSource">
        <property name="packagesToScan" value="com.company" />
        <property name="hibernateProperties">
            <props>
                <!-- Hibernate basic configuration -->
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.generate_statistics">false</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.use_sql_comments">false</prop>
            </props>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="dataSource" ref="testDataSource" />
        <property name="sessionFactory" ref="testSessionFactory" />
    </bean>

    <context:annotation-config />
    <tx:annotation-driven />

    <!-- Initialization of DAOs -->
    <bean id="userDao" name="userDao" class="com.company.dao.UserDAOHibernate" autowire="byName"/>
    ... 
</beans>

org.hibernate.dialogue.mysql5innodbdialogue
假的
假的
更新
假的
... 
在测试类中,我使用了JUnit,因为尽管我尝试扩展AbstractTestNGSpringContextTests,但我还没有成功地使用TestNG。我建议使用JUnit 4.4版本而不是更新的版本,因为它有类似AssumptionViolatedException的类,这些类由SpringTest2.5使用

代码如下:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:src/test/resources/application-config-tests.xml" })
public class SimpleUserDAOTest {

    @Autowired
    private UserDAO dao;

    @Autowired
    private SessionFactory sessionFactory;

    @Before
    public void setUp() throws Exception {
        TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(sessionFactory.openSession()));
    }

    @After
    public void tearDown() throws Exception {
        SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
        SessionFactoryUtils.closeSession(sessionHolder.getSession());
    }

    @Test
    public void shouldReturnActiveUsers() {
        List<User> userList = dao.getActiveUsers();
        ...
    }
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(位置={“文件:src/test/resources/application-config-tests.xml”})
公共类SimpleUserDAOTest{
@自动连线
私用刀刀;
@自动连线
私人会话工厂会话工厂;
@以前
public void setUp()引发异常{
TransactionSynchronizationManager.bindResource(sessionFactory,新会话持有者(sessionFactory.openSession());
}
@之后
public void tearDown()引发异常{
SessionHolder SessionHolder=(SessionHolder)TransactionSynchronizationManager.unbindResource(sessionFactory);
SessionFactoryUtils.closeSession(sessionHolder.getSession());
}
@试验
public void shouldReturnActiveUsers(){
List userList=dao.getActiveUsers();
...
}
}

我希望这对您将来的开发有所帮助

谢谢,通过这一行,sessionFactory已正确初始化。现在我在使用DAO时遇到了问题,因为它启动了HibernateException(“当前线程找不到会话”),尽管我添加了@Transactional之类的注释。我已经找了一段时间了,但还没有找到解决方法。我会在这里评论它,只要我觉得它很高兴,它有帮助。您可以在此处创建新问题并寻求帮助。如果你自己找到了答案,那么就把它贴出来并接受它。在尝试了一段时间后,我决定不这样做。我把它贴在这里作为一个不同的答案,以便其他人将来可以使用它。谢谢你的建议,我已经给了hibernate cfg配置位置。但是由于以下原因导致了以下错误:org.hibernate.service.UnknownUnwrapTypeException:无法在org.hibernate.engine.jdbc.connections.internal.driverManager连接ProviderImpl.unwrap(driverManager连接ProviderImpl.java:222)处展开为请求的类型[javax.sql.DataSource],谢谢。然而,我一直在尝试这段代码,但它对我不起作用,甚至没有启动Hibernate配置。可能我没有正确地注入依赖项,或者无法将其注入测试类。我还尝试过创建JndiConfig对象,并将数据源注入HibernateConfig对象,但没有成功。您是否将所有这些类都放在com.mypackages中了。如果是,请邮寄