Различное поведение / содержимое Spring / Hibernate / SessionFactory при запуске Maven + Surefire и Eclipse + jUnit - PullRequest
1 голос
/ 22 августа 2010

Я стараюсь быть быстрым.

На самом деле, один из моих тестов jUnit не выполняется при запуске команды Maven моего проекта (установка mvn, поэтому с плагином Surefire), в то время как он успешен, когда я запускаю его.в Eclipse.

Я перепробовал много вещей, и единственное отличие, которое мне удалось увидеть, заключается в том, что: - С Maven / Surefire в режиме отладки, в Hibernate-SessionFactory у меня есть только 3 экземпляра EntityPersister - С Eclipse в отладкеВ перспективе я мог бы увидеть 6 экземпляров EntityPersister (на самом деле количество аннотированных классов, которые есть в моем проекте)

Вот мой конфигурационный файл Spring («источник данных» определен в другом проекте, я не помещаю 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);
 }
}

Когда я отлаживаю jUnit в Eclipse, я вижу все 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) 

но при удаленной отладке Surefire через порт 5005 я получил только 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)

Может быть одна важная вещь (это то, что администратор является подпунктомss пользователя):

@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 launcher)?Похоже ли это на ошибку в безошибочной (или где-то еще) или неправильное использование одной из задействованных структур?

Ответы [ 3 ]

0 голосов
/ 22 августа 2010

Я уже где-то читал, что в большинстве случаев расхождение между командной строкой и Eclipse происходит из-за пути к классам. На самом деле, я не потратил время на проверку значений classpath, но это не может быть причиной, так как конфигурационный файл Spring хорошо загружен в обоих случаях, и, поскольку пользователь хорошо загружен, администратор (тот же пакет) также должен быть.

Я застрял с этой проблемой уже несколько дней и случайно исправляю ее через несколько часов после публикации здесь ...! Я не могу в это поверить.

Эта проблема была связана с тем, что у Администратора не было публичного конструктора. Я знаю, что это одна из лучших практик Hibernate / JPA, но обычно возникает явная ошибка («нет публичного ctor» или что-то в этом роде), и мой оставшийся вопрос будет:

Почему поведение отличается от команды mvn и в Eclipse?

0 голосов
/ 22 августа 2010

Не уверен, что это уместно в данном случае, но при разнице между вашей IDE и Maven нужно знать, что Maven по умолчанию будет ссылаться на зависимости, которые есть в вашем локальном репозитории (M2_REPO), тогда как ваша IDE может искать в / цель других модулей. Это особенно верно, если у вас есть мультимодульный проект Maven.

Опять же, -X поможет вам определить путь к классу, который использует Maven. Сравните содержимое пути к классам и порядок пути к ним с тем, с чем запускается ваша IDE.

0 голосов
/ 22 августа 2010

Я считаю, что инструменты, которые вы используете, в порядке.Вы, вероятно, получите ошибку, потому что при запуске из командной строки и при запуске из Eclipse задействованы разные пути к классам.Проверьте вашу файловую структуру в первую очередь.Исходя из того, что вы описали, ваши сущности распределены в разных проектах - попробуйте запустить mvn test -X, чтобы увидеть, какие точные пути к классам использует maven

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...