错误1:
Exception in thread "main" org.hibernate.MappingException: Could not determine type for: com.zhbr.oa.model.Document, for columns: [org.hibernate.mapping.Column(document)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:266)
at org.hibernate.mapping.Column.getSqlTypeCode(Column.java:138)
at org.hibernate.mapping.Column.getSqlType(Column.java:182)
at org.hibernate.mapping.Table.sqlCreateString(Table.java:383)
at org.hibernate.cfg.Configuration.generateSchemaCreationScript(Configuration.java:779)
at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.java:94)
at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.java:61)
at ExprodeDB.main(ExprodeDB.java:15)
分析:原本的类文件和对应的映射文件
package com.zhbr.oa.model;
import java.sql.Date;
/**
* @hibernate.class table="T_AppoveInfo"
*/
public class AppoveInfo {
/**
* @hibernate.id
* generator-class="native"
*/
private int id;
/**
* 审批意见
* @hibernate.property
*/
private String comment;
/**
* 审批时间
* @hibernate.property
*/
private Date approveTime;
/**
* 被审批的公文
* @hibernate.property
*/
private Document document;
/**
* 审批者
* @hibernate.many-to-one
*/
private User approver;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public Date getApproveTime() {
return approveTime;
}
public void setApproveTime(Date approveTime) {
this.approveTime = approveTime;
}
public Document getDocument() {
return document;
}
public void setDocument(Document document) {
this.document = document;
}
public User getApprover() {
return approver;
}
public void setApprover(User approver) {
this.approver = approver;
}
}
对应的映射文件:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class table="T_AppoveInfo" name="com.zhbr.oa.model.AppoveInfo">
<id access="field" name="id">
<generator class="native"/>
</id>
<property name="comment" access="field"/>
<property name="approveTime" access="field"/>
<property name="document" access="field"/>
<many-to-one access="field" name="approver"/>
</class>
</hibernate-mapping>
使用下面的方法建表,抛出上述的异常。
public class ExprodeDB {
public static void main(String []args){
//读取hibernate.cfg.xml文件
Configuration cfg = new Configuration().configure();
SchemaExport export = new SchemaExport(cfg);
export.create(true,true);
}
}
修改方法如下:
(1)将类中
/**
* 被审批的公文
* @hibernate.property
*/
private Document document;
修改为:
/**
* 被审批的公文
* @hibernate.many-to-one
*/
private Document document;
(2)对应的映射文件:
<property name="document" access="field"/>
修改为:
<many-to-one access="field" name="document"/>
错误2:
javax.servlet.ServletException: UsersRoles is not mapped [select r.id from UsersRoles ur join ur.role1 r join ur.user1 u where u.id = ? order by ur.orderNo desc]; nested exception is org.hibernate.hql.ast.QuerySyntaxException: UsersRoles is not mapped [select r.id from UsersRoles ur join ur.role1 r join ur.user1 u where u.id = ? order by ur.orderNo desc]
org.apache.struts.action.RequestProcessor.processException(RequestProcessor.java:535)
org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:433)
org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:414)
javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:174)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:77)
com.zhbr.oa.web.PageAndEncodingFilter.doFilter(PageAndEncodingFilter.java:44)
原因:
类名或类属性名错误
错误3:
下面是摘抄的对hibernate中auot-import属性的分析:
hibernate的实体映射文件(.hbm.xml)里,hibernate-mapping中有一个auto-import属性,默认值为true。
auto-import是什么意思呢? 我们经常会写这样一个HQL语句:
绝大多数时候,这样写是不会发生问题的。 hibernate在处理这个HQL时,会先将其翻译成一条数据库能够识别的sql语句。翻译的依据当然是实体与数据库表之间的映射关系了。 现在我们就给他制造一些问题,我们让hibernate同时管理两个相同名称的实体:org.mysoa.security.model.User和com.kedacom.ksoa.security.model.User。 这时,我们再将上面那条HQL给hibernate解析,他还能顺利地将其翻译成一条sql语句吗?答案当然是否定的,他不知道你要查 org.mysoa.security.model.User还是com.kedacom.ksoa.security.model.User。 所以,一条正确的HQL应该是这样的:
但是,大多数时候,一个系统里不会出现同名的实体,如果要求所有HQL都这么写就不好了。所以hibernate提供一个auto-import属性,当你不指定具体的实体时(只指定from User),他会自动找到唯一的名为User的实体映射,将其补全为org.mysoa.security.model.User。 |
当你的系统中确实要需要两个同名的实体时 当你的系统中确实要需要两个同名的实体时,我们需要做两件事:
有人要问了,只要你做了第二条就够了呀,只要你保证所有的HQL都写了全限定名,那么hibernate解析就不会出错,系统应该是可以运行的。 其实不然。hibernate怎么知道你所有的HQL都写了全限定名?事实上,hibernate在系统加载过程中,如果发现有两个同名的实体,但是有任何一个没有设置auto-import=false,他就会抛出异常并停止加载,他以这种方式来确保你的auto-import问题在系统加载时就暴露出来,而不是延迟到真正执行一个有问题的HQL时才抛出问题。
解决方法: 将User.hbm.xml中加上auto-import="false",但注意在 需要在查询User对象的时候,使用全路径名 <hibernate-mapping auto-import="false"> |