2017-02-27 809 views
1

我是Spring Jpa和Hibernate的新手。我正嘗試從Oracle數據庫中使用自定義函數來獲取數據。我可以定義一個實體及其相關的服務,實現和存儲庫。另外,我將通過使用registerFunction創建一個新的自定義Oracle方言,如下所示。如何在jpa查詢中使用自定義函數?

所以我有兩個問題:

1)在我的Oracle數據庫,該功能位於不同的模式下。我需要指定它的模式嗎?如果是這樣如何?或者休眠會自動找到它?

我會要求我在文章的最後第二個問題提供我的全堆棧跟蹤後...

這裏是我完整的堆棧跟蹤:

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

註釋不要求以';'結尾。只要刪除它。 –

+0

謝謝! @ M.Deinum現在我有上面更新的錯誤。我如何調用我的存儲庫中的輸入值? –

+0

你在'WosItem'上似乎沒有'input'列。你可以發佈你的確切代碼而不需要簡化它嗎? – Strelok

回答

1

不幸的是,如果你想使用你的Select聲明定製function呼叫的JPA 2.1功能,那麼您就需要進行一些額外的動作纔可以使用它。

當您在where語句中使用它,然後它的作品沒有任何額外的行動,但我想用我裏面,就像你做了選擇項目之一,那麼你將需要:

1)延長休眠方言和註冊功能(S):

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())); 

延伸閱讀 - >native function calls

+0

感謝您的答案,但我已經這樣做了。請參閱上面我的應用程序屬性代碼。現在看來我不能調用我的輸入值來在我的倉庫中使用。 –

+0

你試過添加顯式返回類型new StringType()嗎?對不起,我完全錯過了你的問題的開始.. –

+0

btw ..你的WosItem似乎沒有'輸入'字段或我錯過了什麼? –

相關問題