簡體   English   中英

實體中的Spring Roo Service自動接線始終為空(將JPA存儲庫與@RooJpaEntity結合使用)

[英]Spring roo Service auto wiring in entities is always null (Using JPA Repository with @RooJpaEntity)

保存實體時,我一直在尋找一種從服務中調用某些方法的方法。

我的應用是使用Roo 1.2.4.RELEASE創建的

我有一個稱為SaldoCliente的Balance實體和一個名為AuxCliente的ClientAction實體。

每當新的ClientAction實體持續存在時,我都需要更新客戶余額。

這是我的代碼:

@RooJavaBean
@RooToString
@RooJpaEntity(entityName = "AUX_CLIENTES")
public class AuxCliente {


    @Transient
    @Autowired
    static private SaldoClienteService saldoClienteService;


...


    @PostConstruct
    public void init() 
    {
        System.out.println("Initializing with dependency ["+ saldoClienteService + "]");
    }

    @PostPersist
    private void afectaSaldoCliente(/*Long idTrans, Cliente, Integer cargo, BigDecimal importe, Integer creditos*/) {
      if (saldoClienteService == null) {
          System.out.println("saldoClienteService FUE NULL");
      }
...

我不知道為什么saldoClienteService總是為null。

(請注意,我不希望在數據庫中保存saldoClienteService字段,因此不需要@Transient注釋)

我一直在尋找沒有成功的解決方案。 許多解釋說,像這樣在那里說: You need <context:annotation-config/> (or <context:component-scan/>) to enable @PostConstruct handling.

而且我的applicationContext.xml(由Roo創建)中確實有<context:component-scan>

該文件說:

默認情況下,將檢測到Spring提供的@ Component,@ Repository,@ Service和@Controller構造型。 注意:此標記暗含“ annotation-config”標記的作用,在組件類中激活@ Required,@ Autowired,@ PostConstruct,@ PreDestroy,@ Resource,@ PersistenceContext和@PersistenceUnit批注,這對於自動檢測到的組件通常是必需的(無需外部配置)。

至少@Autowired注釋可以在任何地方使用。

有人有指針嗎?

------------------編輯-----------------

首先:感謝@Sotirios和@Ralph抽出寶貴的時間來幫助我。

如果我從字段中刪除“靜態”,則相同。 在我的實體中,注入的字段始終為null。 (請參閱我在此問題中的評論,我補充說這是因為“可能”的解決方案)。

我在另一個需要注射的課程上也遇到了麻煩。 我將此添加到與以前相同的類中(AuxClientes):

@Transient
@Autowired
private ConfigUser configUser;

並且configUser始終也為null。

如果需要的話,這是另一堂課的開始。

@RooJavaBean(settersByDefault=false)
public class ConfigUser {
...

當然,在applicationContext.xml中:

<bean class="com.i4b.adminctes.util.ConfigUser" id="appConfigUser" />

我在構造函數,服務和存儲庫中成功使用configUser。 但不能在實體中使用它。

如果您認為我應該發布代碼的其他部分,請告訴我。

---------------編輯2 ------------------

我所有的實體也一樣。

---------------編輯3.a ------------------

我更改了問題標題,以獲得更好的標題。 在此之前:

Spring Roo(服務自動裝配)實體未調用@PostConstruct。 (通過@RooJpaEntity使用JPA存儲庫)

---------------編輯3.b ------------------

我剛剛創建了一個最小的測試項目。

// Spring Roo 1.2.4.RELEASE [rev 75337cf] log opened at 2013-11-13 11:36:27
project --topLevelPackage org.example --projectName TestAutowiredOnEntities --java 7 --packaging WAR
jpa setup --provider HIBERNATE --database HYPERSONIC_IN_MEMORY 
entity jpa --class ~.domain.MyEntity --testAutomatically --activeRecord false
field string --fieldName text 
repository jpa --interface ~.repository.MyEntityRepository --entity ~.domain.MyEntity
service type --interface ~.service.MyEntityService --entity ~.domain.MyEntity
web mvc setup 
web mvc all --package org.example.web

編輯了服務:

package org.example.service;

public class MyEntityServiceImpl implements MyEntityService {

    @Override
    public String testAutowire() {
        return "Some data";
    }
}

編輯實體:

package org.example.domain;
import javax.persistence.PrePersist;
import javax.persistence.Transient;

import org.example.service.MyEntityService;
import org.example.service.MyEntityServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.roo.addon.javabean.RooJavaBean;
import org.springframework.roo.addon.jpa.entity.RooJpaEntity;
import org.springframework.roo.addon.tostring.RooToString;

@RooJavaBean
@RooToString
@RooJpaEntity
public class MyEntity {

    @Transient
    @Autowired
    MyEntityService myEntityService; 

    /**
     */
    private String text;

    @PrePersist
    public void prePersist() {
        if (myEntityService == null) {
            System.out.println("myEntityService IS NULL");
        } else {
            String data=myEntityService.testAutowire();
            System.out.println("it works: " + data);
            this.text = data;
        }
    } 
}

並編輯了create.jspx以隱藏服務字段。 否則,它不會讓您保存。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:field="urn:jsptagdir:/WEB-INF/tags/form/fields" xmlns:form="urn:jsptagdir:/WEB-INF/tags/form" xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:spring="http://www.springframework.org/tags" version="2.0">
    <jsp:directive.page contentType="text/html;charset=UTF-8"/>
    <jsp:output omit-xml-declaration="yes"/>
    <form:create id="fc_org_example_domain_MyEntity" modelAttribute="myEntity" path="/myentitys" render="${empty dependencies}" z="T0LoTr6PZAwfIQHkjOZMmPW7cO8=">
        <field:input field="myEntityService" id="c_org_example_domain_MyEntity_myEntityService" render="false" z="12sHnsW2dWYyuD+vDtbTve/jWuI="/>
        <field:input field="text" id="c_org_example_domain_MyEntity_text" z="jUCTnP7E3pYPcZcfGn1tyJ2VeFI="/>
    </form:create>
    <form:dependency dependencies="${dependencies}" id="d_org_example_domain_MyEntity" render="${not empty dependencies}" z="Un0bJ/PmWmczxoVTom9NowwIRWk="/>
</div>

然后執行該應用程序並創建一個新的“我的實體”。 將字段留空,我預言了保存按鈕。

日志顯示:

INFO: Reloading Context with name [/testAutowiredOnEntities] is completed
nov 13, 2013 2:31:52 PM org.apache.jasper.compiler.TldLocationsCache tldScanJar
INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
myEntityService IS NULL

並且該實體具有一個空文本字段。

可以肯定的是,我在@MyEntity類中添加了@Component:

...
@Component
@RooJavaBean
@RooToString
@RooJpaEntity
public class MyEntity {
...

沒有改變。 該服務仍然為空。

我真的希望它能幫助比我更了解的人幫助我找到解決方案。

謝謝你們。

同時,我將重新閱讀@Ralph指出的文檔部分。 我顯然做錯了。 我不相信我是唯一需要這個的人。

再次:謝謝大家

Spring不會在static字段中注入。

@RooJavaBean
@RooToString
@RooJpaEntity(entityName = "AUX_CLIENTES")
public class AuxCliente {


    @Transient
    @Autowired
    private SaldoClienteService saldoClienteService;

    @PostPersist
    void afectaSaldoCliente() {
       this.saldoClienteService.doWhatYouWant();
    }

}

關於更新#2

看起來ConfigUser是一個Hibernate / JPA /任何實體,但不是Spring Bean。 但是,您只能注入Spring Bean(例如Services,Dao,...(每一個具有@Component @Controller@Service@Repository @Controller@Service @Controller@Service @Repository批注*的東西)。)

而且,您只能注入使用@Configurable注釋的Spring Bean或類(需要AspectJ), 請參見Spring參考第7.8.1章,使用AspectJ通過Spring依賴注入域對象

使用@Configurable是Spring-Roo的方式(在實體旁邊必須有一個文件AuxCliente_Roo_Configurable.aj (在Eclipse中,它需要禁用“隱藏生成Spring Roo ITD” -Filter才能在Package Explorer中顯示此文件)) 。


*將對象變成彈跳豆還有更多的方法,但這並不重要

終於成功了。

正如我在對@Ralph的最后評論中提到的那樣:添加@Configurable批注可以解決問題。

如果該類如下所示,則自動裝配有效:

@Configurable                <--- added this
@RooPlural("Tarjetas")
@RooJavaBean
@RooToString
@RooJpaEntity
@Table(name = "TARJETAS")
public class Tarjeta {

    @Autowired
    @Transient
    private ConfigUser configUser;

...

但是最后,我決定使用一個幫助器類,以避免所有Spring roo為該屬性生成代碼。 我不想為configUser添加一個私有的getter來防止Spring Roo的public的存在並在所有支架視圖中將'render =“ false”'標記為。

我現在有:

@Configurable
@RooJavaBean
public class Helper {

    @Autowired
    private ConfigUser configUser;

    @Autowired
    private SaldoClienteService saldoClienteService;
}

當我需要自動裝配的bean時,可以使用如下代碼:

ConfigUser configUser = new Helper().getConfigUser();

再次:非常感謝@Ralph

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM