Hibernate与H2
Jar:
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.2.144</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.3.2.GA</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.9.0.GA</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.8</version>
</dependency>
Hibernate配置文件:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/HibernateConfiguration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!--Database connection settings -->
<propertyname="connection.driver_class">org.h2.Driver</property>
<propertyname="connection.url">jdbc:h2:E://Java\\JavaEE\\wordDatabase\\words</property>
<propertyname="connection.username">sa</property>
<propertyname="connection.password"></property>
<!-- JDBCconnection pool (use the built-in) -->
<propertyname="connection.pool_size">1</property>
<!-- SQLdialect -->
<propertyname="dialect">org.hibernate.dialect.H2Dialect</property>
<!-- EnableHibernate's automatic session context management -->
<propertyname="current_session_context_class">thread</property>
<!--Disable the second-level cache -->
<propertyname="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echoall executed SQL to stdout -->
<propertyname="show_sql">true</property>
<!-- Dropand re-create the database schema on startup -->
<propertyname="hbm2ddl.auto">update</property>
<mappingresource="com/gathershell/domain/QueryWord.hbm.xml"/>
<mappingresource="com/gathershell/domain/Word.hbm.xml"/>
</session-factory>
</hibernate-configuration>
对于这个:
<property name="hbm2ddl.auto">none</property>比较奇怪,我之前一直用update可以应对一切情况。但这次不行,只要是update就会报错。org.h2.jdbc.JdbcSQLException: Table"SYSTEM_SEQUENCES" not found; SQL statement:
要先用create去创建数据库和表,然后写成none才行。
发现原因了:
上面的配置是从hibernate的文档中复制改了改的,可惜改的不彻底。
<propertyname="dialect">org.hibernate.dialect.HSQLDialect</property>
这句不对,应该用成H2的。
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
Mapping文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/HibernateMapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mappingpackage="com.gathershell.domain">
<class name="Word" table="Word">
<id name="id">
<generatorclass="native"/>
</id>
<propertyname="name"not-null="true"/>
<propertyname="meaning"not-null="true"></property> </class>
</hibernate-mapping>
Util类创建sessionFactory:
public classHibernateUtil {
private static finalSessionFactory sessionFactory = buildSessionFactory();
private staticSessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return newConfiguration().configure().buildSessionFactory();
}
catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("InitialSessionFactory creation failed." + ex);
throw newExceptionInInitializerError(ex);
}
}
public staticSessionFactory getSessionFactory() {
return sessionFactory;
}
}
Dao的编写:
public booleansave(Word word) {
booleanresult=false;
Session session=HibernateUtil.getSessionFactory().getCurrentSession();
Transactiontx=session.beginTransaction();
try {
String name=word.getName();
if(StringUtil.isBlank(name,word.getName())){
throw newRuntimeException("word name must not null!");
}
Query query=session.createQuery("fromWord where name=?");
query.setString(0, name);
Word databaseWord=(Word)query.uniqueResult();
//if this wordhas not existed in database
if(databaseWord==null){
session.save(word);
result=true;
}else{
logger.debug(name+"hasbe in the database.");
}
tx.commit();
} catch(HibernateException e) {
tx.rollback();
e.printStackTrace();
}finally{
if(session!=null&&session.isOpen()){
session.close();
}
}
returnresult;
}
注意:由于hbm2ddl.auto配置为none,以后数据库要有任何改变,都要按以上步骤,create->none,做一遍。
例如我将一个属性由int改为String直接运行就出现了以下错误:
org.hibernate.exception.GenericJDBCException:could not insert: [com.gathershell.domain.QueryWord]
atorg.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:126)
atorg.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:114)
atorg.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
Caused by: org.h2.jdbc.JdbcSQLException: Dataconversion error converting "'free' (NAME INTEGER NOT NULL)"; SQLstatement:
这种none的配置用作开发后患无穷,因为时常你会忘了去这样做。
6) 某一个属性不能插入数据库
我最后查看数据库发现有一个类的某个属性没有插入数据库中,表中少了这列。后来发现原来在mapping文件中把<property>写成<properties>了,唉,它也没报啥异常,整的我一直没发现。
7) h2数据表不显示外键列
今天在浏览器中查看h2的数据表时,发现外键那一列没有显示,还以为是hibernate配置有问题呢,不过查询时也能查出外键来,看来只是没有显示,数据是在的。
后来发现确实有问题,我要显示一个表格写明商品和它所属的类别,但只有一行显示出来了。后来发现是hibernate配置错了。应是<many-to-one name="bigType"lazy="false"></many-to-one>,却写成了<one-to-one>,唉,它也没报异常。