当我的实体被保存时,我一直在寻找一种从服务中调用某些方法的方法。
我的应用程序是使用 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 总是为空。
(注意我不希望saldoClienteService
在我的数据库中保存一个字段,因此 @Transient 注释)
我一直在寻找没有成功的解决方案。许多解释都是 这样说的,其中说:You need <context:annotation-config/> (or <context:component-scan/>) to enable @PostConstruct handling.
我的 applicationContext.xml 中确实有<context:component-scan>
(由 Roo 创建)。
文档说:
默认情况下,将检测 Spring 提供的 @Component、@Repository、@Service 和 @Controller 构造型。注意:这个标签暗示'annotation-config'标签的效果,激活组件类中的@Required、@Autowired、@PostConstruct、@PreDestroy、@Resource、@PersistenceContext 和@PersistenceUnit 注释,这通常是自动检测组件所需要的(无需外部配置)。
至少@Autowired
注释在任何地方都有效,但在那里。
有人有一些指示吗?
------------------ 已编辑 ------------------
首先:我要感谢@Sotirios 和@Ralph 花时间帮助我。
如果我从字段中删除“静态”,它是一样的。在我的实体中注入的字段始终为空。(请参阅我在这个问题中的评论,由于“可能”的解决方案,我补充说)。
我在另一个需要注入的课程上也遇到了麻烦。我将它添加到与以前相同的类中(AuxClientes):
@Transient
@Autowired
private ConfigUser configUser;
并且 configUser 也始终为空。
这是其他课程的开始,以防万一。
@RooJavaBean(settersByDefault=false)
public class ConfigUser {
...
当然,在 applicationContext.xml 中:
<bean class="com.i4b.adminctes.util.ConfigUser" id="appConfigUser" />
我在构造函数、服务和存储库中成功使用了 configUser。但不能在实体中使用它。
如果您认为我应该发布代码的任何其他部分,请告诉我。
--------------- 编辑 2 ------------------
我所有的实体也是如此。
--------------- 编辑 3.a ------------------
我更改了问题标题,以获得更好的标题。之前是:
Spring roo(服务自动装配)实体未调用 @PostConstruct 。(将 JPA 存储库与 @RooJpaEntity 一起使用)
--------------- 编辑 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
并且实体有一个空的文本字段。
可以肯定的是,我将@Component 添加到“MyEntity”类中:
...
@Component
@RooJavaBean
@RooToString
@RooJpaEntity
public class MyEntity {
...
没有改变。该服务仍然为空。
我真的希望它可以帮助比我更有知识的人帮助我找到解决方案。
谢谢你们。
同时,我将重新阅读@Ralph 指出的文档部分。我显然做错了什么。我不相信我是唯一需要这个的人。
再次:谢谢大家