我是Spring Jpa和Hibernate的新手。我正在尝试使用Oracle数据库中的自定义函数来获取数据。我可以定义一个实体及其相关的服务,实现和存储库。此外,我使用registerFunction
创建了一个新的自定义Oracle方言,如下所示。
所以我有两个问题:
1)在我的Oracle数据库中,该函数位于不同的模式下。我需要指定其架构吗?如果是这样的话?或者hibernate会自动找到它吗?
在提供完整的堆栈跟踪后,我将在本文末尾提出第二个问题......
这是我的完整堆栈跟踪:
MyOracle10gDialect
package blog;
import org.hibernate.dialect.Oracle10gDialect;
import org.hibernate.dialect.function.StandardSQLFunction;
public class MyOracle10gDialect extends Oracle10gDialect {
public MyOracle10gDialect() {
super();
registerFunction("my_function", new StandardSQLFunction("my_function"));
}
}
application.properties
...
spring.jpa.database-platform=blog.MyOracle10gDialect
...
实体:
package blog.models;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "item", schema = "WOS_SOURCE")
public class WosItem {
@Id
@Column(nullable = false)
private String UT;
@Column(nullable = false)
private String TI;
public String getUT() {
return UT;
}
public void setUT(String UT) {
this.UT = UT;
}
public String getTI() {
return TI;
}
public void setTI(String TI) {
this.TI = TI;
}
public WosItem(String UT, String TI) {
this.UT = UT;
this.TI = TI;
}
public WosItem() { }
@Override
public String toString() {
return "WosItem{" +
"UT='" + UT + '\'' +
", TI='" + TI + '\'' +
'}';
}
}
服务
package blog.services;
import blog.models.WosItem;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public interface WosItemService {
List<WosItem> findAll();
WosItem findById(String id);
String find_ut(Long ut_seq);
}
实施
package blog.services;
import blog.models.WosItem;
import blog.repositories.WosItemRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class WosItemServiceJpaImpl implements WosItemService {
@Autowired
private WosItemRepository wosItemRepository;
@Override
public List<WosItem> findAll() {
return this.wosItemRepository.findAll();
}
@Override
public WosItem findById(String id) {
return this.wosItemRepository.findOne(id);
}
@Override
public String find_ut(Long ut_seq) {
return this.wosItemRepository.find_ut();
}
}
存储库:
package blog.repositories;
import blog.models.WosItem;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
@Repository
public interface WosItemRepository extends JpaRepository<WosItem, String> {
@Query("SELECT function('my_function', input) FROM WosItem wos");
String find_ut();
}
所以在我的Oracle数据库中我可以使用这个函数,如下所示:
select other_schema.my_function(aa.input) from my_schema.TABLE aa;
对于前。假设aa.input为332708100009
,则返回000332708100009
至于我的第二个问题:
2)我如何在jpa中执行此过程?我知道我的存储库根本不正确。我得到一个错误,如“这里不允许注释”。我无法找到解决这个问题的方法。
提前致谢。
以上编辑:
Caused by: java.lang.IllegalStateException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode
\-[METHOD_CALL] MethodNode: 'function (my_function)'
+-[METHOD_NAME] IdentNode: 'my_function' {originalText=my_function}
\-[EXPR_LIST] SqlNode: 'exprList'
\-[NAMED_PARAM] ParameterNode: '?' {name=ut_seq, expectedType=null}
答案 0 :(得分:3)
不幸的是,如果您想在function
语句中使用自定义Select
调用的JPA 2.1功能,则需要先执行一些其他操作才能使用它。
当你在where
语句中使用它时,它可以在没有任何其他操作的情况下工作,但是因为我想将它用于我在select中的一个项目,就像你一样,你需要:
1)扩展hibernate方言并注册你的功能:
package com.mypkg.dialect;
import org.hibernate.dialect.Oracle10gDialect;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.type.StringType;
public class CustomOracle10gDialect extends Oracle10gDialect {
public CustomOracle10gDialect() {
super();
registerFunction("my_function"
, new StandardSQLFunction("my_function", new StringType()));
}
}
2)编辑会话工厂的hibernate.dialect
属性以指向该自定义实现:
<property name="hibernate.dialect" value="com.mypkg.dialect.CustomOracle10gDialect"/>
<强>更新强>
如果需要从某个模式调用该函数,则会建议:
registerFunction("my_function"
, new StandardSQLFunction("schema.my_function", new StringType()));
进一步阅读 - &gt; native function calls