使用HIBERNATE调用自定义函数

    最近的项目打算用SPRINGMVC+HIBERNATE来实现,因为我们打算把这个项目做成一个产品,所以使用HIBERNATE希望

可以部署在不同的数据库服务器上。

    但是使用HQL调用自定义函数的时候却出现了问题。比如 select user.id, my_function(user.id) from USER u,执行这个HQL

会报如下的错误:

java.lang.IllegalStateException: No data type for node: org.hibernate.hql.ast.tree.MethodNode
 \-[METHOD_CALL] MethodNode: '('
    +-[METHOD_NAME] IdentNode: 'my_function' {originalText=my_function}

    在网上找了下,解决方法是重写对应的数据库方言,然后配置到hibernate.dialect上,但是考虑到以后切换到不同的数据库,

需要重写对应的方言,反而影响程序的跨平台性。因为如果我的函数采用标准SQL,HIERNATE调用本地SQL的时候并不影响跨平台

性(我想的没问题吧?)。

    所以我打算直接用HIBERNATE调用本地SQL,这个方法有很多,我用的是采用NAMED-SQL方式,把SQL写在配置文件里,

这样也方便维护。


        
        
           
                classpath:com/wei/liu/springmvc/czyw/**/*.hbm.xml
           

       

        
            
                ${hibernate.hbm2ddl.auto}
                ${hibernate.dialect}
                ${hibernate.show_sql}
                ${hibernate.format_sql}
            

        

        
            com.xxx.xxx..
        

    

    因为我采用的是注解的方式映射的实体类,所以XXX.hbm.xml只有SQL语句,如下:

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
 
 
       
         
                         SELECT id,my_function(id) from user
        ]]>  
 
 

    这样在java中就可以直接通过session来调用这条语句了 

session.getNamedQuery("selectXXX").setFirstResult(begin).setMaxResults(pageSize).list();

    这里要注意的是,select后面要把所有的字段都写出来,不然的话会报如下的错误:

org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute query; nested exception is org.hibernate.exception.SQLGrammarException: could not execute query
Caused by: org.hibernate.exception.SQLGrammarException: could not execute query
Caused by: java.sql.SQLException: Invalid column name XXXX(少的那个列名).

    如果不想写映射文件,也可以把SQL写在对应的实体类中,如下:

@Entity
@Table(name = "XXX", schema = "XXX", catalog = "XXX")
@NamedNativeQuery(name = "XXX", query = "XXX")
public class XXXimplements java.io.Serializable {

    把对应的XXX替换掉即可。


   


你可能感兴趣的:(hibernate)