自己遇到的hibernate常見錯誤
1>
錯誤顯示: net.sf.hibernate.PropertyValueException: not-null property references a null or transient value: com.Order.customer
部分原文件:( customer 和 order 類關系:一對多關聯)
Order.hbm.xml
……………
<
many-to-one
???????
name
=
"customer"
???????
column
=
"CUSTOMER_ID"
???????
class
=
"com.Customer"
???????
not-null
=
"true"
???????
cascade
=
"save-update"
?????
????
/>
執行文件:
………
Session session = sessionFactory.openSession();
??? Transaction tx = null;
??? try {
????? // Create some data and persist it
???? tx = session.beginTransaction();
?
???? Customer customer=new Customer();
???? customer.setName("Jack");
????
???? Order order=new Order();
???? order.setOrderNumber("Jack_Order001");
???????? session.save(customer);
???????? session.save(order);
?? tx.commit();
原因分析:因為在執行代碼中,沒有將 customer 和 order 類一對多關聯起來,若單獨持久化兩個類: session.save(customer);session.save(order); 則在保存 order 的時候,由于 CUSTOMER_ID是與 customer類外鍵,因此無法讀取 customer_id, 而在 order.hbm.xml 中指定其不為空,則產生了以上錯誤。
問題解決:
not-null
=
"true"
改為:not-null="false" 雖然程序無問題,但order表 CUSTOMER_ID為空,不符合邏輯。應該將指定其一對多的關聯。
order.setCustomer(customer);
????? customer.getOrders().add(order);
?
2〉
錯誤顯示:
RROR SessionImpl:2400 - Could not synchronize database state with session
net.sf.hibernate.exception.GenericJDBCException: could not delete collection: [com.Customer.orders#2]
部分原文件:
Session session = sessionFactory.openSession();
??? Transaction tx = null;
??? try {
????? tx = session.beginTransaction();
????? Customer customer=(Customer)session.load(Customer.class,new Long(3));
????? session.delete(customer);
????? tx.commit();
原因分析:因為
cascade默認值為
none,所以當刪除customer時,不會自動刪除與其關聯的order對象。
問題解決:添加語句
cascade
=
"delete"
?
3>
錯誤顯示:
17:24:34,992 ERROR JDBCExceptionReporter:58 - [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]在關鍵字 'ORDER' 附近有語法錯誤。
17:24:34,992? WARN JDBCExceptionReporter:57 - SQL Error: 156, SQLState: HY000
17:24:35,002 ERROR JDBCExceptionReporter:58 - [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]在關鍵字 'ORDER' 附近有語法錯誤。
17:24:35,022? WARN JDBCExceptionReporter:34 - SQL Warning: 0, SQLState:
net.sf.hibernate.exception.GenericJDBCException
: could not initialize collection: [com.Customer.orders#2]
部分原文件: order.hbm.xml
<
hibernate-mapping
>
?
<
class
name
=
"com.Order"
table
=
"ORDER"
>
????
<
id
name
=
"id"
type
=
"long"
column
=
"ID"
>
???????
<
generator
class
=
"increment"
/>
?????
</
id
>
??
<
property
name
=
"orderNumber"
type
=
"string"
>
???????
<
column
name
=
"ORDER_NUMBER"
length
=
"15"
/>
?????
</
property
>
?????
?????
<
many-to-one
???????
name
=
"customer"
???????
column
=
"CUSTOMER_ID"
???????
class
=
"com.Customer"
???????
outer-join
=
"true"??
??????
/>
原因分析:因為 order 表在 SQL 2000 數據庫中已經定義了,如果用戶在定義了 order 表,并且程序對該表進行連接等操作就會出錯
問題解決:將 引用 order 處改為 [order]
<
class
name
=
"com.Order"
table
=
"[ORDER]"
>
?
4>
net.sf.hibernate.exception.SQLGrammarException
: Could not save object
??? at net.sf.hibernate.exception.SQLStateConverter.convert(
SQLStateConverter.java:58
)
??? at net.sf.hibernate.exception.JDBCExceptionHelper.convert(
JDBCExceptionHelper.java:29
)
??? at net.sf.hibernate.impl.SessionImpl.convert(
SessionImpl.java:4131
)
??? at net.sf.hibernate.impl.SessionImpl.saveWithGeneratedIdentifier(
SessionImpl.java:794
)
??? at net.sf.hibernate.impl.SessionImpl.save(
SessionImpl.java:749
)
??? at com.BusinessService.saveCategoryWithCascade(
BusinessService.java:54
)
??? at com.BusinessService.test(
BusinessService.java:104
)
??? at com.BusinessService.main(
BusinessService.java:109
)
Caused by:
java.sql.SQLException
: [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]對象名 'CATEGORIES' 無效。
5〉
錯誤顯示: net.sf.hibernate.MappingException : Resource: Add valid path not found
部分原文件: hibernate.hbm.xml
<
hibernate-configuration
>
?
<
session-factory
>
???
<
property
name
=
"connection.username"
>
sa
</
property
>
???
<
property
name
=
"connection.url"
>
jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=test
</
property
>
???
<
property
name
=
"dialect"
>
net.sf.hibernate.dialect.SQLServerDialect
</
property
>
???
<
property
name
=
"myeclipse.connection.profile"
>
MSSQL
</
property
>
???
<
property
name
=
"connection.password"
>
hheryh
</
property
>
???
<
property
name
=
"connection.driver_class"
>
com.microsoft.jdbc.sqlserver.SQLServerDriver
</
property
>
???
<
mapping
resource
=
"Add valid path"
/>
</
session-factory
>
原因分析:找不到有效的 xml 文件
問題解決:將所有配置文件都加到 resource 里
將<
mapping
resource
=
"Add valid path"
/>改為
<
mapping
resource
=
"com/Customer.hbm.xml"
/>
<
mapping
resource
=
"com/Order.hbm.xml"
/>
6〉
錯誤顯示
net.sf.hibernate.MappingException
: Error reading resource: com/Customer.hbm.xml
??? at net.sf.hibernate.cfg.Configuration.addResource(
Configuration.java:340
)
??? at net.sf.hibernate.cfg.Configuration.doConfigure(
Configuration.java:1027
)
??? at net.sf.hibernate.cfg.Configuration.doConfigure(
Configuration.java:983
)
??? at net.sf.hibernate.cfg.Configuration.configure(
Configuration.java:911
)
??? at net.sf.hibernate.cfg.Configuration.configure(
Configuration.java:897
)
??? at com.BusinessService.<clinit>(
BusinessService.java:17
)
Caused by:
net.sf.hibernate.MappingException
: duplicate import: Customer
??? at net.sf.hibernate.cfg.Mappings.addImport(
Mappings.java:85
)
??? at net.sf.hibernate.cfg.Binder.bindClass(
Binder.java:126
)
??? at net.sf.hibernate.cfg.Binder.bindRootClass(
Binder.java:221
)
??? at net.sf.hibernate.cfg.Binder.bindRoot(
Binder.java:1256
)
??? at net.sf.hibernate.cfg.Configuration.add(
Configuration.java:253
)
??? at net.sf.hibernate.cfg.Configuration.addInputStream(
Configuration.java:289
)
??? at net.sf.hibernate.cfg.Configuration.addResource(
Configuration.java:337
)
??? ... 5 more
部分原文件
:hibernate.hbm.xml
<?
xml
version
=
'1.0'
encoding
=
'UTF-8'
?>
<!
DOCTYPE
hibernate-configuration
PUBLIC
?????????
"-//Hibernate/Hibernate Configuration DTD 2.0//EN"
?????????
"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd"
>
?
<!-- Generated by MyEclipse Hibernate Tools.?????????????????? -->
<
hibernate-configuration
>
?
<
session-factory
>
???
<
property
name
=
"connection.username"
>
sa
</
property
>
???
<
property
name
=
"connection.url"
>
jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=test
</
property
>
???
<
property
name
=
"dialect"
>
net.sf.hibernate.dialect.SQLServerDialect
</
property
>
???
<
property
name
=
"myeclipse.connection.profile"
>
MSSQL
</
property
>
???
<
property
name
=
"connection.password"
>
hheryh
</
property
>
???
<
property
name
=
"connection.driver_class"
>
com.microsoft.jdbc.sqlserver.SQLServerDriver
</
property
>
???
<
mapping
resource
=
"com/Customer.hbm.xml"
/>
</
session-factory
>
?
</
hibernate-configuration
>
?
主程序:
static{
???? try{
????? // Create a configuration based on the properties file we've put
?????? Configuration config = new Configuration();
?????? config.addClass(Customer.class);
????? // Get the session factory we can use for persistence
????? sessionFactory = config
????? .configure()
????? .buildSessionFactory();
??? }catch(Exception e){e.printStackTrace();}
?
? }
解決方法:
config.addClass(Customer.class);
sessionFactory = config.configure().buildSessionFactory();
原因分析:
hibernaet
配置文件有兩種格式,一種是
xml
格式,一種是普通的
.property
格式
.
在 1.2 版本中,編譯時自動會在 path 路徑中查找 property 格式的配置文件。但不會查詢 xml 格式的配置文件,因此需要在程序中手動添加 config.configure() ,但此時就不要加載了。
上面的程序 加載了一次 config.configure() ,又映射了一次,所以出錯。
?
解決方法:
若配置文件為 xml 格式的,程序編寫如下:
// Create a configuration based on the properties file we've put
?????? Configuration config = new Configuration();
???????????? // Get the session factory we can use for persistence
????? sessionFactory = config
????? .configure()
.buildSessionFactory();
?
若配置文件為 property 格式的,程序編寫如下:
// Create a configuration based on the properties file we've put
?????? Configuration config = new Configuration();
?????? config.addClass(Customer.class);
????? // Get the session factory we can use for persistence
????? sessionFactory = config.buildSessionFactory();
?