2017-09-25 2 views
0

J'ai une fonction définie par l'utilisateur dans MS SQL Server appelée à partir du code Java qui semble être indéfinie lors de l'exécution des tests d'intégration dans la base de données H2. Vous pouvez trouver mon code au the previous question.DbUnit - JdbcSQLException: La fonction "*" est introuvable

Code d'essai:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = {H2Config.class}) 
@TestExecutionListeners({ 
     DependencyInjectionTestExecutionListener.class, 
     DbUnitTestExecutionListener.class, 
     TransactionalTestExecutionListener.class 
}) 
@TransactionConfiguration(defaultRollback = true) 
public class TableDaoTest { 

    @Autowired 
    private TableDao tableDao; 

    @Test 
    @DatabaseSetup("/datasets/import.xml") 
    public void testMethod01() { 
     tableDao.getRecordsByGroup(); 
     ... 

schéma de base de données est générée automatiquement par Hibernate. Comme vous pouvez voir les données pour le test est peuplé par DbUnit en utilisant le jeu de données XML. Et ce test échoue car ma fonction qui existe dans la base de données du serveur MS SQL n'est pas définie dans la base de données H2.

journal d'application:

Caused by: org.hibernate.exception.GenericJDBCException: could not prepare statement 
    ... 
Caused by: org.h2.jdbc.JdbcSQLException: Function "SAFE_MOD" not found; SQL statement: 
    select table10_.id, table10_.value, ... from Table1 table10_ where table10_.group1=dbo.safe_mod(?, ?); 
    ... 

Comment importer/créer une fonction avant le test DbUnit?

Répondre

0

La base de données H2 ne prend pas en charge les fonctions SQL définies par l'utilisateur. Cependant, dans cette base de données, les fonctions Java peuvent également être utilisées comme procédures stockées.

@SuppressWarnings("unused") 
public class H2Function { 
    public static int safeMod(Integer n, Integer divider) { 
     if (divider == null) { 
      divider = 5000; 
     } 

     return n % divider; 
    } 

} 

Notez que seules les méthodes Java statiques sont prises en charge; la classe et la méthode doivent toutes deux être publiques.

La fonction Java doit être déclarée (enregistrée dans la base de données) en appelant CREATE ALIAS ... FOR avant de pouvoir être utilisé:

CREATE ALIAS IF NOT EXISTS safe_mod DETERMINISTIC FOR "by.naxa.H2Function.safeMod"; 

Cette déclaration doit être exécutée avant tout test si j'ai décidé de le mettre dans SQL init de connexion :

@Bean 
public DataSource dataSource() { 
    BasicDataSource dataSource = new BasicDataSource(); 

    dataSource.setDriverClassName("org.h2.Driver"); 
    dataSource.setUrl("jdbc:h2:mem:my_db_name"); 
    dataSource.setUsername("sa"); 
    dataSource.setPassword(""); 
    dataSource.setConnectionInitSqls(Collections.singleton(
     "CREATE ALIAS IF NOT EXISTS safe_mod DETERMINISTIC FOR \"by.naxa.H2Function.safeMod\";")); 

    return dataSource; 
}