I'm creating a web application with Spring 3.1.0.RELEASE and JPA 2 with Hibernate Provider.
I'm doing the test with junit 4.10 , dbunit 2.4.8, unitils 3.3, hsqldb 2.2.8.
I try to test the service layer, a create operation. In my DAO i have this method:
#Override
#Transactional
public void createQuestion(Question question) {
logger.debug("createQuestion");
entityManager.persist(question);
logger.info("New question created [id] {}", question.getId());
}
My QuestionServiceTest test class :
#SpringApplicationContext("test-applicationContext.xml")
public class QuestionServiceTest extends UnitilsJUnit4 {
#SpringBeanByName
private QuestionService questionService;
#SpringBeanByName
private ThemeService themeService;
#Test
#DataSet("QuestionServiceTest.testCreateQuestion.xml")
#ExpectedDataSet("QuestionServiceTest.testCreateQuestion-result.xml")
public void testCreateQuestion() {
final Question newQuestion = new Question();
newQuestion.setCountryCode("FR");
newQuestion.setEmail("test#mytest.com");
newQuestion.setFirstName("FirstTest");
newQuestion.setLastName("LastTest");
newQuestion.setOriginalLang(LanguageEnum.FR);
newQuestion.setOriginalQuestion("This is the original question");
final Calendar calendar = Calendar.getInstance();
calendar.set(2012, 5, 12);
newQuestion.setCreationDate(calendar.getTime());
final Theme theme = themeService.findThemeById(new Integer(1));
newQuestion.setTheme(theme);
questionService.createQuestion(newQuestion);
}
}
I use the property hibernate.hbm2ddl.auto = create-drop for generate the schema, the question table is:
create table question (
id integer generated by default as identity (start with 1),
country_code varchar(10) not null,
creation_date timestamp not null,
email varchar(255) not null,
firstname varchar(100) not null,
lastname varchar(100) not null,
original_lang varchar(255) not null,
original_question clob not null,
theme_id integer not null,
primary key (id)
)
theme_id is a foreign key to table theme.
When i launch the test with ExpectedDataSet, the insert works but the test never finish.
The test block on :
DEBUG: org.dbunit.database.AbstractResultSetTable - Query: select
"ID", "COUNTRY_CODE", "CREATION_DATE", "EMAIL", "FIRSTNAME",
"LASTNAME", "ORIGINAL_LANG", "ORIGINAL_QUESTION", "THEME_ID" from
"PUBLIC"."QUESTION" order by "ID"
This is the last line on debug.
My unitils.properties is :
# Defaults and other keys with explanations can be found there: http://unitils.org/unitils-default.properties
database.driverClassName=org.hsqldb.jdbcDriver
database.url=jdbc:hsqldb:mem:testOpen
database.userName=sa
database.password=
database.dialect=hsqldb
# This schema is the initial schema when a new session is started in HSQLDB, don't change it or test won't works !
database.schemaNames=PUBLIC
dbUnit.datasetresolver.prefixWithPackageName=false
dbUnit.datasetresolver.pathPrefix=dataSets
My persistence.xml :
<persistence-unit name="OpenTestPU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
<property name="hibernate.connection.username" value="sa" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:testOpen" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
</properties>
</persistence-unit>
What should I do? I already try previous release of dbunit or unitils but it doesn't change anything. Expected Dataset is really cool feature.
Thanks.
I had the same issue and failed to solve it. Then I gave a try to
spring-test-dbunit
and this lib run smoothly.
Related
I am new to spring batch , the csv file for example
Employee Name Id age year
Department DeptName deptId desc
Department DeptName deptId desc
Employee Name Id age year
Department DeptName deptId desc
Department DeptName deptId desc
This is my format
If that employer with name exists mysql will throw DataIntegrityViolationException
So i added
<batch:skippable-exception-classes>
<batch:include class="org.springframework.dao.DataIntegrityViolationException" />
</batch:skippable-exception-classes>
So this will skip the whole unit the corresponding Employer and Department records
what I have to do even if the Employee exists and throws this Exception
Then to continue with Department.
I would recommend to use item classifier
public class ItemTypeClassifier {
#Classifier
public String classify(Item item) {
return item.getType();// returns "Employee", "Department"
}
}
Then a router implementation with two different item writer, one for employee and one for department.
<bean id="classifier" class="org.springframework.batch.classify.BackToBackPatternClassifier">
<property name="routerDelegate">
<bean class="ItemTypeClassifier" />
</property>
<property name="matcherMap">
<map>
<entry key="Employee" value-ref="emplyeeItemWriter" />
<entry key="Department" value-ref="departmentItemWriter" />
</map>
</property>
</bean>
And then
<bean id="ItemWriter" class="org.springframework.batch.item.support.ClassifierCompositeItemWriter">
<property name="classifier" ref="classifier" />
</bean>
Now that you have two different writer, you can run two steps inside your job by defining two separate skippable exceptions configuration for them.
I am working on a java application using JSF and hibernate and the database is oracle.
this is my entity class---------
#Entity
#Table(name="docUpload")
#SequenceGenerator(name="seqGen",sequenceName="docseq")
public class DocDetailsEntity {
#Id
#GeneratedValue(generator="seqGen",strategy=GenerationType.SEQUENCE)
private Integer docId;
private String docName;
private String docDesc;
private String userId;
#Lob
private Clob doc;
table scrips--------
create table docUpload
(
docId number(10) primary key,
docName varchar2(50) not null,
docDesc varchar2(100),
userId varchar2(10) not null,
doc clob not null
);
CREATE SEQUENCE docseq
START WITH 100
INCREMENT BY 1
NOCACHE
NOCYCLE;
hibernate.cfg.xml-----
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- hibernate dialect -->
<property name="hibernate.dialect"> org.hibernate.dialect.OracleDialect </property>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:#xxxxx:1521:xx</property>
<property name="hibernate.connection.username">xxxx</property>
<property name="hibernate.connection.password">xxxx</property>
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<!-- Automatic schema creation (begin) === -->
<property name="hibernate.hbm2ddl.auto">none</property>
<!-- Simple memory-only cache -->
<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- <property name="show_sql">true</property> -->
<mapping class="entity.DocDetailsEntity"/>
</session-factory>
</hibernate-configuration>
but i am getting this error when i am trying to persist the entity into the db
org.hibernate.exception.SQLGrammarException: could not extract ResultSet
.
.
.
.
Caused by: java.sql.SQLSyntaxErrorException: ORA-02289: sequence does not exist
please suggest me a solution
Could you please try to write as
#Table(name="docUpload",schema = "schemaName" )
#SequenceGenerator(name="seqGen",sequenceName="schemaName.seqName")
I'm trying to use an HSQLDB in order to run some integration test.
I use Spring.
Hibernate is used to set up the database schema.
Then I want to insert test data using liquibase.
My problem is that, while hibernate schema creation works fine, I'm getting :
liquibase.exception.DatabaseException: Error executing SQL INSERT INTO PUBLIC.OxAttributeType (id, "alias") VALUES ('1', 'varchar'): user lacks privilege or object not found: alias
When liquibase try to start it's insertion.
I think that it might be cause by the hsqldb beeing closed (and flushed) after hibernate schema creation, but I'm not sure.
Here is my configuration:
database.properties:
jdbc.driverClassName= org.hsqldb.jdbc.JDBCDriver
jdbc.url=jdbc:hsqldb:mem:oxandtestdatabase
jdbc.username: SA
jdbc.password:
Hibernate object:
#Entity
#Table(name = "oxattribute")
public class Oxattribute implements java.io.Serializable {
private Integer id;
private String alias;
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "alias", nullable = false, length = 30)
public String getAlias() {
return this.alias;
}
}
Spring configuration:
<bean id="hibernateProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<!-- <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> -->
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
</bean>
<bean id="liquibase" class="liquibase.integration.spring.SpringLiquibase">
<property name="dataSource" ref="dataSource" />
<property name="changeLog" value="classpath:liquibase/testData.xml" />
</bean>
So Hibernate is working, I can see in the logs:
Hibernate: create table oxattribute (id integer generated by default as identity (start with 1), alias varchar(30) not null, deletable boolean not null, description varchar(255), idOxAttributeType integer not null, idOxObject integer not null, primary key (id))
But then when liquibase start insertions:
SEVERE 07/08/14 13:59: liquibase: classpath:liquibase/testData.xml: classpath:liquibase/testData.xml::insertMetadata::GCH: Change Set classpath:liquibase/testData.xml::insertMetadata::GCH failed. Error: Error executing SQL INSERT INTO PUBLIC.OxAttributeType (id, "alias") VALUES ('1', 'varchar'): user lacks privilege or object not found: alias
liquibase.exception.DatabaseException: Error executing SQL INSERT INTO PUBLIC.OxAttributeType (id, "alias") VALUES ('1', 'varchar'): user lacks privilege or object not found: alias
For information, my code was working fine on a mysql database.
Thank you for your help,
Guillaume
Change the name of the column used ("alias" is reserved term). You could try adding backticks "`".
#Column(name="`alias`").
Hi I'm trying a little POC with JPA and unit test to verify that the DB schema is created. I'm working with H2 DB and I set to Hibernate create the schema from the entities, but when DbUnit tries to initialize the DB from a dataset I always get a Table ... not found in tableMap. I read that I have to add the property DB_CLOSE_DELAY=-1 to DB URL but is like after Hibernate creates the schema the DB is losted when DbUnit tries to initialize.
Any ideas? Any help is highly appreciated.
This is my config:
application-context.xml
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSourceH2" />
<property name="packagesToScan" value="com.xxx.model" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="true" />
<property name="showSql" value="true" />
<!-- property name="databasePlatform" value="org.hibernate.dialect.MySQLInnoDBDialect" /-->
<property name="databasePlatform" value="org.hibernate.dialect.H2Dialect" />
<!-- property name="database" value="MYSQL" /-->
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="javax.persistence.validation.mode">CALLBACK</prop>
</props>
</property>
</bean>
<bean id="dataSourceH2"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
RepositoryTest.java
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "/application-context-test.xml" })
#Transactional
public class SystemEntityRepositoryH2Test {
#Inject
private SystemEntityRepository repository;
#Inject
private DataSource dataSourceH2;
private IDatabaseConnection connection;
#Before
public void setUp() throws Exception {
IDatabaseConnection dbUnitCon = null;
dbUnitCon = new DatabaseDataSourceConnection(dataSourceH2, "testdb");
dbUnitCon.getConfig().setProperty(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);
IDataSet dataSet = this.getDataSet("dataset-systementity.xml");
DatabaseOperation.INSERT.execute(dbUnitCon, dataSet);
}
#After
public void tearDown() throws Exception {
//DatabaseOperation.DELETE_ALL.execute(this.getConnection(), this.getDataSet(dataSetFile));
}
#Test
public void test() throws Exception {
}
protected IDataSet getDataSet(String dataSetFile) throws Exception {
ResourceLoader resourceLoader = new ClassRelativeResourceLoader(this.getClass());
Resource resource = resourceLoader.getResource(dataSetFile);
if (resource.exists()) {
return new FlatXmlDataSetBuilder().build(resource.getInputStream());
}
return null;
}
}
dataset-systementity.xml
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<System_Entities id="2" name="NAME" phone01="+52-55-55555555" email="a#a.com"
address01="Street" address02="123" address03="1" address04="Address04"
address05="Address05" city="City" state="State" country="MX"
zipcode="12345" />
</dataset>
Error
ERROR DatabaseDataSet:286 - Table 'System_Entities' not found in tableMap=org.dbunit.dataset.OrderedTableNameMap[_tableNames=[], _tableMap={}, _caseSensitiveTableNames=false]
I can see that the tables are created by hibernate because the log shows all the sql sentences without error.
Thanks.
SOLUTION
Thanks Mark Robinson
I modified the setUp method to:
#Before
public void setUp() throws Exception {
IDatabaseConnection dbUnitCon = null;
EntityManager entityManager = entityManagerFactory.createEntityManager();
Session session = entityManager.unwrap(Session.class);
SessionImplementor si = (SessionImplementor) session;
Connection conn = si.getJdbcConnectionAccess().obtainConnection();
dbUnitCon = new DatabaseConnection(conn);
//dbUnitCon.getConfig().setProperty(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);
IDataSet dataSet = this.getDataSet("dataset-systementity.xml");
DatabaseOperation.INSERT.execute(dbUnitCon, dataSet);
}
It works now, what I don't understand yet is if I use HSQLDB I don't have this problem.
The problem is that DBUnit is loading the table data before Hibernate can initialize.
As part of your #setup, you'll need to get the Hibernate session. This should cause Hibernate to create your table. You could even force it by executing a simple query like select 1
I have a unique constraint on one property of my entity:
Table(uniqueConstraints = #UniqueConstraint(name = "UniqueByEmail", columnNames = "email"))
public class Player implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(name = "email")
private String email;
...
}
In my DAO i want to throw an appropriate exception when something tries to create a new player that would violate this constraint:
public Player create(String email, String password) {
Player player = new Player(email, password);
try {
em.persist(player);
} catch (Exception e) {
System.err.println("I GOT AN EXCEPTION : " + e.getClass());
}
return player;
}
Unfortunately nothing happens. when i call flush() on the entity manager i get the persistence exception as a result of this call, but not when i call persist().
This behaviour differs from the behaviour of hibernate, so i think i misconfigured something.
Any help is greatly appreciated.
Persistence.xml:
org.eclipse.persistence.jpa.PersistenceProvider
model.GameInstanceAccount
Player
spring applicationContext.xml:
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="persistence-unit" />
<property name="jpaDialect" ref="jpaDialect" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter" />
</property>
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" />
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.eclipse.persistence.platform.database.HSQLPlatform" />
</bean>
when i call flush() on the entity manager i get the persistence
exception as a result of this call, but not when i call persist()
This is expected behaviour. The persist call only attaches the transient entity to the current persistence session making it managed. The constraint applies in the database and so will only be applied when the persistence session is flushed and new entities are inserted to the database.
This is summed up in this blog as follows:
A newly created instance of the entity class is passed to the persist
method. After this method returns, the entity is managed and planned
for insertion into the database. It may happen at or before the
transaction commits or when the flush method is called.