エンティティが保存されているときに、サービスからメソッドを呼び出す方法を探していました。
私のアプリは 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 が指摘したドキュメント セクションを読み直します。私は明らかに何か間違ったことをしています。これを必要としているのは私だけだとは思いません。
改めまして:皆様ありがとうございました