常见错误及解决方法

时间:2021-05-28 20:55:47

 错误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语句:

from User u where u.name='罗灿锋';

绝大多数时候,这样写是不会发生问题的。

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应该是这样的:

from org.mysoa.security.model.User u where u.name='罗灿锋';

但是,大多数时候,一个系统里不会出现同名的实体,如果要求所有HQL都这么写就不好了。所以hibernate提供一个auto-import属性,当你不指定具体的实体时(只指定from User),他会自动找到唯一的名为User的实体映射,将其补全为org.mysoa.security.model.User。

常见错误及解决方法 当你的系统中确实要需要两个同名的实体时

当你的系统中确实要需要两个同名的实体时,我们需要做两件事:

  1. 将这两个同名的实体的映射文件都要设置为auto-import
  2. 所有关于这两个实体的HQL,都需要明确指定其全限定名(如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">
  <class table="T_User" name="com.zhbr.oa.model.User">
    <id access="field" name="id">
      <generator class="native"/>
    </id>
    <property name="username" not-null="true" access="field" unique="true"/>
    <property name="password" not-null="true" access="field"/>
    <property name="createTime" access="field" update="false"/>
    <property name="expireTime" access="field"/>
    <many-to-one unique="true" access="field" name="person"/>
  </class>
</hibernate-mapping>