问题:
在JAVA工程中,数据库使用的是OracleXE(Oracle10g Express Edition)。 使用hibernate.reveng.xml创建了实体类及其DAO类,如:
tt.myutils.dao
|--User.java
|--UserHome.java
|--User.hbm.xml
由于没有JNDI容器,因此对UserHome.java进行了如下修改,使代码能够运行:
protected SessionFactory getSessionFactory() { try { Configuration cfg = new Configuration().configure(); Properties p = cfg.getProperties(); StandardServiceRegistryBuilder b = new StandardServiceRegistryBuilder().applySettings(p); ServiceRegistry sr = b.build(); return cfg.buildSessionFactory(sr); } catch (Throwable ex) { System.out.println("创建SessionFactory时出错!"+ex); throw new ExceptionInInitializerError(ex); } }
主程序也很简单:
package tt; import tt.myutils.dao.User; import tt.myutils.dao.UserHome; public class Tester { public static void main(String[] args) { UserHome gh = new UserHome(); User obj = gh.findById("张三"); System.out.println("获取记录信息:" + obj.getPwd()); } }
调试程序,出现以下“表名无效”错误(也可能是“SQL 命令未正确结束”):
将上述SQL语句输出拷贝到SQL PL下执行,也报同样错误,说明是Hibernate生成的SQL语句语法有问题。
分析:
oracle建表时,如果建表的SQL同时满足以下条件,则不论在查询或新增数据时都必须把相应SQL中的表名用引号括起来,否则会报00942错误。
条件1. 建表的SQL中表名、列名用引号 " 括起来了。
条件2. 建表的SQL中表名中英文字符不全部都是大写。
试用Navcat等工具建立Oracle表时,是必须添加引号的,如Navcat工具生成的脚本:
CREATE TABLE "BIZ"."NewTable" ( "ID" NUMBER(4) NULL , "NAME" VARCHAR2(32) NULL , "ADDRESS" VARCHAR2(64) NULL ) NOCOMPRESS ;
也就是说,用工具生成的表,以后ORACLE只识别带 " 的SQL
解决办法:
在User.hbm.xml中解决,靠手工吧:把出现的所有表、列用""括起来。而XML不能直接插入",必须用XML转义符"如下所示:
<hibernate-mapping> <class name="tt.myutils.dao.User" table=""USER""> <id name="usr" type="string"> <column name=""USR"" length="30" /> <generator class="assigned" /> </id> <property name="pwd" type="string"> <column name=""PWD"" length="64" /> </property> </class> </hibernate-mapping>
现在,Hibernate输出的SQL语句变成了
select user0_."USR" as USR1_0_0_, user0_."PWD" as PWD2_0_0_ from BIZ."USER" user0_ where user0_."USR"=?
结果就正确了。
总结:
Oracle的语法搞的鬼。
n