【发布时间】:2011-04-02 07:12:07
【问题描述】:
我尽量快。
事实上,当我在 Eclipse 中运行它时,运行项目的 Maven 命令(mvn install,因此使用 Surefire 插件)时,我的一个 jUnit 测试失败了。
我尝试了很多东西,但我设法看到的唯一区别是: - 在调试模式下使用 Maven/Surefire,在 Hibernate-SessionFactory 我只有 3 个 EntityPersister 实例 - 使用 Eclipse 在调试透视图中,我可以看到 6 个 EntityPersister 实例(实际上是我项目中的 annotatedClasses 的数量)
这是我的 Spring 配置文件(“dataSource”是在另一个项目中定义的,我没有放 DAO 类):
<beans ...>
<!-- le gestionnaire de BLOB / CLOB de chez Spring -->
<bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" />
<!-- Hibernate SessionFactory Definition -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
<property name="dataSource">
<ref bean="datasource" />
</property>
<property name="packagesToScan">
<list>
<value>com.wft.model</value>
<value>com.wft.model.user</value>
</list>
</property>
<!--
<property name="annotatedClasses">
<list>
<value>com.wft.model.Project</value>
<value>com.wft.model.Authors</value>
<value>com.wft.model.user.User</value>
<value>com.wft.model.user.Administrator</value>
<value>com.wft.model.user.Gamer</value>
<value>com.wft.model.user.Organizer</value>
</list>
</property>
-->
</bean>
<!-- Hibernate Transaction Manager Definition -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- TODO: Switch to annotations for transactions
<tx:annotation-driven/>
-->
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!-- -->
<bean id="autoProxyCreator"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<idref local="transactionInterceptor" />
</list>
</property>
<property name="beanNames">
<list>
<value>*DAO</value>
</list>
</property>
</bean>
<bean id="projectDAO" class="com.wft.service.dao.impl.ProjectDAO">
<constructor-arg>
<value>com.wft.model.Project</value>
</constructor-arg>
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<bean id="userDAO" class="com.wft.service.dao.impl.UserDAO">
<constructor-arg>
<value>com.wft.model.user.User</value>
</constructor-arg>
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
</beans>
还有测试课:
public class TestDAO extends
AbstractTransactionalDataSourceSpringContextTests {
private IUserDAO userDAO;
private IProjectDAO projectDAO;
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
protected String[] getConfigLocations() {
return new String[] { "classpath*:myapp-persistence-tech.xml",
"classpath*:datasource_mysql.xml" };
}
@Override
protected boolean isDefaultRollback() {
return false;
}
@Override
protected boolean isRollback() {
return false;
}
/**
* Spring will automatically inject userDAO object on startup
*
* @param userDAO
*/
public void setUserDAO(IUserDAO userDAO) {
this.userDAO = userDAO;
}
/**
* Spring will automatically inject projectDAO object on startup
*
* @param projectDAO
*/
public void setProjectDAO(IProjectDAO projectDAO) {
this.projectDAO = projectDAO;
}
public void test1() {
System.out.println("Session Factory : "+sessionFactory);
@SuppressWarnings("unused")
SessionFactoryImpl sfImpl = (SessionFactoryImpl)sessionFactory;
Administrator admin = new Administrator("admin", "admin");
User user1 = new User("user1", "user1");
User user2 = new User("user2", "user2");
for (User user : userDAO.findAll()) {
if (user instanceof Administrator) {
System.out.println("Deleting administrator");
} else {
System.out.println("Deleting user");
}
userDAO.delete(user);
}
userDAO.add(user1);
userDAO.add(admin);
// dao.add(user2);
System.out.println();
assertTrue(true);
}
}
当我在 Eclipse 中调试 jUnit 时,我可以看到所有的 EntityPersisters :
entityPersisters HashMap<K,V> (id=75)
entrySet HashMap$EntrySet (id=87)
keySet null
loadFactor 0.75
modCount 6
size 6
table HashMap$Entry<K,V>[16] (id=95)
threshold 12
values HashMap$Values (id=136)
但是在端口 5005 上远程调试 Surefire 时,我只得到了 3 个……
它以 :
结尾test1(com.wft.service.services.TestDAO) Time elapsed: 2.139 sec <<< ERROR!
org.hibernate.MappingException: Unknown entity: com.wft.model.user.Administrator
at org.hibernate.impl.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:580)
可能有一件重要的事情(管理员是用户的子类):
@Entity
@Table(name = "USER")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="DTYPE", discriminatorType=DiscriminatorType.STRING, columnDefinition="VARCHAR(32) DEFAULT \"ROLE_USER\"", length=32)
@DiscriminatorValue(value="ROLE_USER")
@ForceDiscriminator
public class User extends LightEntity implements Serializable {}
@Entity
@DiscriminatorValue(value="ROLE_ADMINISTRATOR")
@ForceDiscriminator
public class Administrator extends User {}
但继承似乎不是根本原因。
有人知道这两种环境(Maven+Surefire 与 Eclipse+jUnit 启动器)之间的这种差异吗? 它看起来像是surefire(或其他地方)中的错误还是所涉及的框架之一的错误使用?
【问题讨论】:
-
如果你把
Administrator注释掉怎么办?从命令行运行时能看到User吗?
标签: java unit-testing hibernate spring maven-2