1

エンティティが保存されているときに、サービスからメソッドを呼び出す方法を探していました。

私のアプリは 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 である理由がわかりません。

(DBにフィールドを保存したくないsaldoClienteServiceので、 @Transient アノテーションを使用することに注意してください)

私は成功せずに解決策を探してきました。説明の多くは、次のよう に言っいます。You need <context:annotation-config/> (or <context:component-scan/>) to enable @PostConstruct handling.

そして<context:component-scan>、私の applicationContext.xml (Roo によって作成されたもの) に含まれています。

ドキュメントには次のように記載されています。

デフォルトでは、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>

次に、アプリケーションを実行し、新しい「My Entity」を作成しました。フィールドを空のままにして、保存ボタンを押しました。

ログには次のように表示されます。

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 {
...

何も変わっていません。サービスはまだ null です。

私よりも知識のある人が解決策を見つけるのを手伝ってくれることを本当に願っています.

皆さん、ありがとうございました。

それまでの間、@Ralph が指摘したドキュメント セクションを読み直します。私は明らかに何か間違ったことをしています。これを必要としているのは私だけだとは思いません。

改めまして:皆様ありがとうございました

4

2 に答える 2

0

最後にそれが機能しました。

@Ralph への最後のコメントで述べたように、 @Configurable アノテーションを追加するとうまくいきました。

クラスが次のようになっている場合、自動配線は機能します。

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

    @Autowired
    @Transient
    private ConfigUser configUser;

...

しかし、最後に、Spring roo が生成したこの属性のコードをすべて回避するために、ヘルパー クラスを使用することにしました。Spring Roo の公開ゲッターが存在するのを防ぎ、すべてのスキャフォールド ビューで「render="false"」をマークするために、configUser のプライベート ゲッターを追加したくありません。

今私が持っています:

@Configurable
@RooJavaBean
public class Helper {

    @Autowired
    private ConfigUser configUser;

    @Autowired
    private SaldoClienteService saldoClienteService;
}

自動配線された Bean が必要な場合は、次のようなものを使用します。

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

繰り返しますが、どうもありがとうございました@Ralph

于 2013-11-26T12:14:54.747 に答える