generating database from hibernate entities - java

I have mysql db from which I generated the hibernate entities, now I need to generate in-memory database from these entities for testing. I got this error while trying to run my unit test.
/***
main] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 42102, SQLState: 42S02
2016-02-16 18:10:47.864 ERROR 29758 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : Table "tbl_all_orders" not found; SQL statement:
**/
It looks like the db creation failed.
Here is my testing properties file content:
db.driver: org.h2.Driver
db.url: jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=false
db.username: sa
db.password:
hibernate.dialect: org.hibernate.dialect.H2Dialect
hibernate.show_sql: true
hibernate.format_sql: true
hibernate.hbm2ddl.auto: create
hibernate.archive.autodetection=class, hbm
entitymanager.packagesToScan: linda

This is my example for h2 testing. You can alter it a bit and see where it fits in your case. mainly you need to create db tables manually and let your config.xml to have your db included.
You can create .sql file manually and create tables and let the bean to include it if you are using spring.
someTest.java
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("testConfig.xml") // <-- this xml you need to include
public class PortDaoImplTest {
private static final Logger log = Logger.getLogger(sysInfoDaoImplTest.class);
#Autowired
private sysInfoDaoImpl sysDao;
#After
public void tearDown(){
portDao = null;
}
#Test
public void testGetPort() {
log.info("Testing getInfo(String id)...");
SysInfo p = sysDao.getInfo("nysdin2039");
assertNotNull(p);
}
testConfig.xml
...xml header...
<!-- h2 driver -->
<bean id="test.dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" lazy-init="false" >
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:mem:test_mem;DB_CLOSE_DELAY=-1;MODE=ORACLE" />
</bean>
<!-- datasource file -->
<jdbc:initialize-database data-source="test.dataSource">
<!-- table list -->
<jdbc:script location="com/yourPath/h2/schema.sql" />
<jdbc:script location="com/yourPath/h2/test_data.sql" />
</jdbc:initialize-database>
<!-- bean def -->
<bean id="sysInfoDao" class="com.mycompanyName.sysInfoDaoImpl" >
<property name="log" ref="test.log" />
<property name="dataSource" ref="test.dataSource" />
</bean>
....
h2 schema.sql file
drop table IF EXISTS tbl_all_orders;
CREATE TABLE tbl_all_orders
(
your_stuff_ID NUMBER NOT NULL,
your_other_column_stuff VARCHAR2(15) DEFAULT
);
...add your constrains or columns accordingly...
test_data.sql file
INSERT into tbl_all_orders
(your_column_names... , your_other_column_names...)
VALUES
(1, 'values',...);

this is my working configuration for testing (database.properties inside src/test/resources folder)
# DB properties
db.driver=org.h2.Driver
db.url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
db.username=sa
db.password=
# Hibernate Configuration
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=true
# validate: validate the schema, makes no changes to the database.
# update: update the schema.
# create: creates the schema, destroying previous data.
# create-drop: drop the schema at the end of the session.
hibernate.hbm2ddl.auto=create
entitymanager.packages.to.scan=abcde
btw, your unit tests shouldn't be hitting the database.

Related

How can I configure JPA for a postgres database schema?

I have an existing postgres database with the database "testdb" and the database schema testdbschema".
If I use the default persistence.xml configuration of RESOURCE_LOCAL the following property is working:
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://server:port/testdb?currentSchema=testdbschema" />
I want to configure my database connection within my web.xml as a data-source. Everything is working well, except the configuration of the database schema.
Here is my web.xml configuration:
<data-source>
<name>java:global/myapp</name>
<class-name>org.postgresql.ds.PGSimpleDataSource</class-name>
<server-name>127.0.0.1</server-name>
<port-number>5432</port-number>
<database-name>testdb</database-name>
<user>postgres</user>
<password>postgres</password>
</data-source>
Do you now how can I configure my db schema name here?
The configuration via testdb?currentSchema=testdbschema did not work for me and I get a database not found failure.
The solution was found within the PGSimpleDataSource:
<data-source>
<name>java:global/myapp</name>
<class-name>org.postgresql.ds.PGSimpleDataSource</class-name>
<server-name>127.0.0.1</server-name>
<port-number>5432</port-number>
<database-name>testdb</database-name>
<user>postgres</user>
<password>postgres</password>
<property>
<name>currentSchema</name>
<value>testdbschema</value>
</property>

Hibernate: create SQL Server 2012 database table in non-default schema

I'm trying to use Hibernate to create a table in a SQL Server 2012 database.
I set a number of properties in my Java project's persistence.xml file:
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServer2012Dialect" />
<property name="hibernate.hbm2ddl.auto" value="auto" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.use_sql_comments" value="false" />
... and set the database connection details in when UI create my data source, which is done in a configuration Java class:
dataSource.setDriverClassName(myDriver); // com.microsoft.sqlserver.jdbc.SQLServerDriver
dataSource.setUrl(myUrl); // jdbc:sqlserver://host:port;DatabaseName=dbname
dataSource.setUsername(myUser);
dataSource.setPassword(myPwd);
In the Java class, I also set the default schema when I create the Java Persistence entity manager factory:
final Map<String, Object> jpaProperties = new HashMap<>();
jpaProperties.put("hibernate.default_schema", "mySchema");
entityManagerFactory.setJpaPropertyMap(jpaProperties);
entityManagerFactory.afterPropertiesSet();
return entityManagerFactory.getObject();
The Java domain class has been annotated as follows:
#Entity
#Table(name = "mytable")
public class MyTable {
...
}
The schema called "mySchema" has been created in the SQL Server database and authorization has been granted to the user specified in the data source.
When I try and run the functionality which should create the table as part of the first run (and populate it appropriately), I get the following error message:
SQLServerException: Invalid object name 'mySchema.mytable'
... and the table has not been created in the schema.
The Hibernate SQL looks like this:
select alias0_.ID as alias1_0_0_
... other columns...
from mySchema.mytable alias0_
where alias0_.ID=?
I'm using version 1.0.0.Final of the hibernate-jpa-2.1-api JAR in my Java project.
Thanks in advance for any assistance.

Identity Generation with MySql and H2 for local testing

I'm new here, so I hope it's not a stupid question.
I am using a MySQL DB and am trying to use an H2 DB alongside for local tests. I am running into problems when persisting new objects, i.e., objects that do not yet have an Id. It works fine on the running system using MySQL, but currently the local tests in H2 fail with the following exception:
javax.persistence.PersistenceException: org.hibernate.HibernateException: The database returned no natively generated identity value
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1377)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1306)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:871)
...
Caused by: org.hibernate.HibernateException: The database returned no natively generated identity value
at org.hibernate.id.IdentifierGeneratorHelper.getGeneratedIdentity(IdentifierGeneratorHelper.java:90)
at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:100)
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:58)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2936)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3447)
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:203)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:183)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:167)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:320)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:287)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:126)
at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:78)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:78)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:843)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:818)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:822)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:865)
... 33 more
I use the following persistence annotations in the corresponding Java class:
#Entity
#Table( name = "myclass" )
public class MyClassDbo {
private MyClassId id;
#Id
#Column( nullable = false )
#GeneratedValue( strategy = GenerationType.AUTO )
#Type( type=MyClassIdType.FQ_CLASS_NAME )
public MyClassId getId() {
return this.id;
}
...
}
The persistence configuration looks like this. For production:
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.url" value="jdbc:mysql://#my.db.host#/#my.db.schema#"/>
<property name="hibernate.connection.username" value="#my.db.user#"/>
<property name="hibernate.connection.password" value="#my.db.password#"/>
For local tests:
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.url" value="jdbc:h2:mem:db1;MODE=MySQL;DB_CLOSE_DELAY=-1;MVCC=true;INIT=create schema IF NOT EXISTS generic" />
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
The MySQL DB is setup with the following SQL:
CREATE TABLE MYCLASS
( ID BIGINT PRIMARY KEY AUTO_INCREMENT, ... )
The H2 DB is setup using a testdata.xml
<?xml version='1.0' encoding='UTF-8'?>
<dataset>
<MYCLASS ID="1" .../>
</dataset>
with the following code
JdbcDatabaseTester databaseTester = new JdbcDatabaseTester( "org.h2.Driver", "jdbc:h2:mem:db1;MODE=MySQL;DB_CLOSE_DELAY=-1;MVCC=true;INIT=create schema IF NOT EXISTS generic;", "sa", "" );
File file = new File( "testdata.xml" );
databaseTester.setDataSet( new FlatXmlDataSetBuilder().build( file ) );
databaseTester.setSetUpOperation( DatabaseOperation.CLEAN_INSERT );
databaseTester.setTearDownOperation( DatabaseOperation.NONE );
return databaseTester;
and when I look into the H2 DB, everything looks correct to me, the ID column is marked to be the primary key and has a default value which generates an ID.
I am using the following versions:
Java 7
MySQL Connector 5.1.40
Hibernate 4.1.9
H2 1.3.173
DB Unit 2.4.9
I have not found a way to make MySQL and H2 work together here. I have tried different GenerationTypes and the only idea I have right now is to create my own IdentityGenerator which depending on the setup either manually creates an Id for the H2 DB or behaves like the standard IdentityGenerator for MySQL. However, with this I deploy code dedicated for testing into the running system which I would like to avoid.
Thanks for any ideas and suggestions! And please tell me if I forgot any important information.

org.h2.jdbc.JdbcSQLException: Table "ALL_SEQUENCES" not found

Could someone please tell me the reasons for the below error.
I am using Hibernate in my project and face the below error during server startup
15:04:27.909 [localhost-startStop-1] ERROR o.h.tool.hbm2ddl.SchemaValidator - HHH000319: Could not get database metadata
org.h2.jdbc.JdbcSQLException: Table "ALL_SEQUENCES" not found; SQL statement:
select sequence_name from all_sequences union select synonym_name from all_synonyms us, all_sequences asq where asq.sequence_name = us.table_name and asq.sequence_owner = us.table_owner [42102-168]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:329) ~[h2-1.3.168.jar:1.3.168]
at org.h2.message.DbException.get(DbException.java:169) ~[h2-1.3.168.jar:1.3.168]
at org.h2.message.DbException.get(DbException.java:146) ~[h2-1.3.168.jar:1.3.168]
at org.h2.command.Parser.readTableOrView(Parser.java:4770) ~[h2-1.3.168.jar:1.3.168]
at org.h2.command.Parser.readTableFilter(Parser.java:1084) ~[h2-1.3.168.jar:1.3.168]
at org.h2.command.Parser.parseSelectSimpleFromPart(Parser.java:1690) ~[h2-1.3.168.jar:1.3.168]
This happens when you use either a wrong dialect in your persistence-unit inside your persistence.xml, or you validate against the wrong database. For example, when you run your application against a local H2 database, the best choice would be to remove the dialect, since Hibernate can recognize the database without this property (if the Version of Hibernate is new enough to recognize newer databases). Another solution would be to remove the validate attribute, but I would not recommend that, since you have no database checks at startup then:
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
</properties>
I used multiple dataSources
OracleDb1Configuration
#Primary
#Bean(name = "oracleDb1EntityManager")
public LocalContainerEntityManagerFactoryBean oracleDb1EntityManagerFactory(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(oracleDb1DataSource)
.properties(hibernateProperties())
.packages("com.fengxin58.user.ddd.domain.model.oracle.db1")//设置实体类所在位置
.persistenceUnit("oracleDb1PersistenceUnit")
.build();
}
private Map<String, Object> hibernateProperties() {
String env = monitorService.env();
if(log.isDebugEnabled()) {
log.debug("current profile: {}", env);
}
Resource resource = null;
if(EnvEnum.TEST.key().equals(env)) {
resource = new ClassPathResource("hibernate-oracle-db1-test.properties");
}else {
resource = new ClassPathResource("hibernate-oracle-db1.properties");
}
try {
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
return properties.entrySet().stream()
.collect(Collectors.toMap(
e -> e.getKey().toString(),
e -> e.getValue())
);
} catch (IOException e) {
return new HashMap<String, Object>();
}
}
hibernate-oracle-db1-test.properties
hibernate.hbm2ddl.auto=update
application-test.yml
oracle:
db1:
datasource:
url: jdbc:h2:mem:test
driver-class-name: org.h2.Driver
username: root
password:
db2:
datasource:
url: jdbc:h2:mem:test
driver-class-name: org.h2.Driver
username: root
password:
You have to ensure that the table and the sequence is created. If it is created, then it will work.
The table "ALL_SEQUENCES" is not created. Please check your database is it exists or not?
Your problem is the sequence is not created as well as the table is not created.
Solution:
Check your hibernate.cfg.xml. It is not configured well.
For your clarification, I have given a cfg file below:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">org.h2.Driver</property>
<property name="connection.url">jdbc:h2:database/test</property>
<property name="connection.username">sa</property>
<property name="connection.password"/>
<property name="hibernate.default_schema">PUBLIC</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<mapping class="au.com.ozblog.hibernate.h2.example.User"/>
</session-factory>
</hibernate-configuration>
In my case, I was using multiple datasources in my application, and using H2 for tests.
In this case, you have to set manually the dialect in JPA properties of the datasource, not via application.properties file.
Map<String, Object> properties = new HashMap<>();
properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
return builder
.dataSource(ds)
.packages("com.application.demo")
.properties(properties)
.persistenceUnit("persitenceUnit1")
.build();
In every datasource used.
In case it can help someone.
regards

How to use HSQLdb with Ibatis

I want to use in memory database to query for data in my unit testing, my project is Ibatis (with annotation) for querying actual database which I want to mimic with the help of HSQLDB.
Please help me with how to configure iBatis with HSQLDB.
Also is there any way to these better for unit testing with code which is strongly dependent on database in its functions.
You can make an iBatis sqlMappings.xml config file something like this:
<sql-map-config>
<properties resource="configuration.properties" />
<!--The datasource for you application is configured here: -->
<datasource name = "hsql"
factory-class="com.ibatis.db.sqlmap.datasource.SimpleDataSourceFactory"
default="true">
<property name="JDBC.Driver" value=""/>
<property name="JDBC.ConnectionURL" value=""/>
<property name="JDBC.Username" value=""/>
<property name="JDBC.Password" value=""/>
</datasource>
<!--Declare the SQL Maps to be loaded for this application.
Be sure it's in your classpath. -->
<sql-map resource="maps/beanMappings.xml"/>
</sql-map-config>
plus a congifuration.properties file like this:
JDBC.Driver=org.hsqldb.jdbcDriver
JDBC.ConnectionURL=jdbc:hsqldb:hsql://localhost/myDb
JDBC.Username=sa
JDBC.Password=
and then use it like this:
String resource = "maps/SqlMapConfig.xml";
Reader reader = Resources.getResourceAsReader(resource);
SqlMap sqlMap = XmlSqlMapBuilder.buildSqlMap(reader);

Categories