Spring数据MongoDb无法转换代理bean

时间:2013-10-06 02:48:32

标签: spring mongodb aop aspectj mappingexception

我正在使用带有AspectJ和Spring Data MongoDb的Spring AOP,并且在持久化对象时遇到了麻烦。

在这种情况下,我有一个公开AclEntryImpl的AclEntryDaoImpl。当为AclEntryImpl提供作为标准Java对象的Principal(“非Spring”bean)时,mongoTemplate.save()按预期工作。但是,当Principal是Spring bean时,Mongo无法转换对象并导致MappingException org.springframework.data.mapping.model.MappingException: No id property found on class class com.sun.proxy.$Proxy33。我的所有对象都需要是Spring bean,以便(a)我保持我的对象解耦,并且(b)调用我的AOP(LoggingAspect)。

最后,我无法利用Spring转换器,因为Mongo将目标对象AclEntryImpl视为代理com.sun.proxy.$Proxy33,因此永远不会调用Converter<Principal, DBObject>

非常感谢任何和所有帮助!

片断:

这是我的Spring XML配置:

<beans>
    <context:component-scan base-package="a.b" />
    <context:property-placeholder location="config.properties" />
    <aop:aspectj-autoproxy />

    <bean id="loggingAspect" class="a.b.LoggingAspect" />

    <mongo:db-factory host="${database.host}" port="${database.port}" dbname="${database.dbname}" />

    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
    </bean>

    <bean id="aclEntryDao" class="a.b.AclEntryDaoImpl">
        <lookup-method name="createAclEntry" bean="aclEntry" />
    </bean>

</beans>

AclEntryImpl:

@Document
@Component
@Scope("prototype")
public class AclEntryImpl implements AclEntry {

    @Id
    private String id;

    private String service;

    @DBRef @Expose
    private Principal principal;

    @Expose
    private boolean accessGranted;

    @Expose
    private List<Permission> permissions;

    @Override @Loggable @MongoSaveReturned
    public AclEntry save() {
        return this;
    }

    ...getters and setters...

}

AclEntryDaoImpl:

@Repository
public abstract class AclEntryDaoImpl implements AclEntryDao {

    @Override @Loggable
    public AclEntry addEntry(String serviceName, Principal principal, Permission[] permissions, boolean accessGranted) throws Exception {
        AclEntry entry = createAclEntry(); //<-- Spring lookup-method
        entry.setService(serviceName);
        entry.setPrincipal(principal); //<-- com.sun.proxy.$Proxy33
        entry.setAccessGranted(accessGranted);
        for (Permission permission : permissions) {
            if (!entry.addPermission(permission)) {
                return null;
            }
        }
        return entry.save();
    }

    ... other DAO methods ...

}

LoggingAspect:

@Aspect
public class LoggingAspect {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Pointcut("execution(!void a.b..*.*(..))")
    public void returningMethods() {}

    @AfterReturning(pointcut="returningMethods() && @annotation(MongoSaveReturned)", returning="retVal")
    public Object mongoSaveReturnedAdvice(Object retVal) {
        Logger logger = null;
        try {
            logger = getLogger(retVal);
            mongoTemplate.save(retVal); //<-- throws MappingException
            log(logger, "save:    " + retVal.toString());
        } catch (Exception e) {
            log(logger, "throw:   " + e.toString());
        }
        return retVal;
    }

    ... other logging methods ...

}

0 个答案:

没有答案