【问题标题】:Why is Spring Data unable to detect the IsNewStrategy for MongoDB auditing?为什么 Spring Data 无法检测到 IsNewStrategy for MongoDB 审计?
【发布时间】:2015-08-20 17:38:57
【问题描述】:

我正在尝试启用 Spring Data MongoDB 审计。但是每当我试图启动我的服务器时,我都会遇到错误。你能告诉我这里有什么问题吗?我正在使用 Spring 4.1.6 和 Spring Data MongoDB 1.7.0。

SEVERE: Exception sending context initialized event to listener instance of class
 org.springframework.web.context.ContextLoaderListener
 java.lang.IllegalArgumentException: Unsupported entity
 com.idearealty.product.shopchat.persistence.model.IdeaRealtyUser!
 Could not determine IsNewStrategy.    at
 org.springframework.data.support.IsNewStrategyFactorySupport.getIsNewStrategy(IsNewStrategyFactorySupport.java:48)
   at
 org.springframework.data.auditing.IsNewAwareAuditingHandler.markAudited(IsNewAwareAuditingHandler.java:80)
   at
 org.springframework.data.mongodb.core.mapping.event.AuditingEventListener.onApplicationEvent(AuditingEventListener.java:54)
   at
 org.springframework.data.mongodb.core.mapping.event.AuditingEventListener.onApplicationEvent(AuditingEventListener.java:31)
   at
 org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:151)
   at
 org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:128)
   at
 org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:331)
   at
 org.springframework.data.mongodb.core.MongoTemplate.maybeEmitEvent(MongoTemplate.java:1609)
   at
 org.springframework.data.mongodb.core.MongoTemplate.doInsert(MongoTemplate.java:792)
   at
 org.springframework.data.mongodb.core.MongoTemplate.insert(MongoTemplate.java:742)
   at
 org.springframework.data.mongodb.repository.support.SimpleMongoRepository.save(SimpleMongoRepository.java:76)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  at
 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
   at
 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:606)     at
 org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:434)
   at
 org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:419)
   at
 org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:391)
   at
 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
   at
 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
   at com.sun.proxy.$Proxy62.save(Unknown Source)  at
 com.idearealty.product.shopchat.config.SetupDataLoader.onApplicationEvent(SetupDataLoader.java:52)
   at
 com.idearealty.product.shopchat.config.SetupDataLoader.onApplicationEvent(SetupDataLoader.java:1)
   at
 org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:151)

以下是实体代码

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;

import javax.persistence.Id;

import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.annotation.Transient;
import org.springframework.data.annotation.TypeAlias;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;

/**
 * @author Debopam
 *
 */
@Document(collection="IdeaRealtyUser")
@TypeAlias("user")
public class IdeaRealtyUser extends User implements UserDetails,Serializable {

    @Id
    private String id;

    private String email;
    private String phoneNumber;
    private String role;
    private String firstName;
    private String lastName;
    private Address address;
    //private String password;
    @Transient
    private String matchingPassword;

    @CreatedDate
    protected Date createDate;

    @LastModifiedDate
    protected Date lastModifiedDate;
    @CreatedBy
    protected String createdBy;
    @LastModifiedBy
    protected String lastModifiedBy;
 //getter and setter
}

和配置

<bean id="mongo" class="org.springframework.data.mongodb.core.MongoFactoryBean">
        <property name="host" value="localhost" />
    </bean>
    <mongo:mongo host="127.0.0.1" port="27017">
       <mongo:options connections-per-host="8"
                   threads-allowed-to-block-for-connection-multiplier="4"
                   connect-timeout="1000"
                   max-wait-time="1500"
                   auto-connect-retry="true"
                   socket-keep-alive="true"
                   socket-timeout="1500"
                   slave-ok="true"
                   write-number="1"
                   write-timeout="0"
                   write-fsync="true"/>
    </mongo:mongo>
    <mongo:db-factory dbname="shopchatdb" mongo-ref="mongo"/>
    <!--  
    <mongo:auditing mapping-context-ref="customMappingContext" auditor-aware-ref="com.idearealty.product.util.MongoAuditAware"/>
    -->
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg ref="mongo"/>
        <constructor-arg name="databaseName" value="mongo"/>
    </bean>

    <mongo:auditing auditor-aware-ref="ideaRealtyAudit"/>
    <context:component-scan base-package="com.idearealty.product.shopchat" />

【问题讨论】:

    标签: java spring mongodb spring-data-mongodb spring-mongo


    【解决方案1】:

    问题在于 Spring 如何确定实体或模型的基本包。覆盖 getMappingBasePackage() 方法可解决此问题。下面是Spring Mongodb配置文件

    @Configuration
    //@EnableTransactionManagement
    @PropertySource({ "classpath:persistence.properties" })
    @ComponentScan(basePackages={ "com.idearealty.product.persistence.model" })
    @EnableMongoRepositories(basePackages = "com.idearealty.product.repository.mongodb")
    @EnableMongoAuditing
    public class PersistenceMongoConfig extends AbstractMongoConfiguration{
    
        @Autowired
        private Environment env;
    
        public PersistenceMongoConfig() {
            super();
        }
    
        @Bean(name="mongoAudit")
        public AuditorAware<String> mongoAuditProvider() {
            return new MongoAuditAware();
        }
    
    
        @Override
        protected String getDatabaseName() {
            return "shopdb";
        }
    
        @Override
        public Mongo mongo() throws Exception {
            return new MongoClient(new ServerAddress("localhost", 27017),mongoClientOptions());
        }
    
        @Bean
        public MongoClientOptions mongoClientOptions() {
            // override to more reasonable connection timeout (default is 10 seconds)
            return MongoClientOptions.builder().connectTimeout(1500)
                    .connectionsPerHost(8)
                    .maxWaitTime(1500)
                    .socketKeepAlive(true)
                    .build();
        }
    
        @Override
        protected String getMappingBasePackage() {
            return "com.product.persistence.model";
        }
    
    }
    

    【讨论】:

    • 如果我在不扩展 AbstractMongoConfig 的情况下进行配置,如何提供 mappingbasepackage
    【解决方案2】:

    要解决此错误,请声明 &lt;mongo:mapping-converter /&gt; 并配置 base-package 属性以指向包含您的域类的包。确保使用 MongoTemplate 构造函数,该构造函数接受 MongoDbFactoryMongoConverter 并连接相应的 bean 定义。

    除此之外,您的配置看起来很可疑。您声明了两个生成 Mongo 实例的 bean(一个通过工厂,一个通过命名空间)。此外,现在建议宁愿使用MongoClient 实例。

    简化到最低限度的最简化配置应如下所示:

    <!-- put options here -->
    <mongo:mongo-client id="mongo" … />
    
    <mongo:db-factory id="db-factory" mongo-ref="mongo" />
    
    <!-- put your domain package here -->
    <mongo:mapping-converter id="converter" base-package="…" />
    
    <bean class="….MongoTemplate">
       <constructor-arg ref="db-factory" />
       <constructor-arg ref="converter" />
    </bean>
    
    <mongo:auditing …/>
    

    【讨论】:

    • 现在我遇到了错误类 org.springframework.beans.factory.BeanCreationException:创建名为“converter.mongoMappingContext”的 bean 时出错:调用 init 方法失败;嵌套异常是 com.mongodb.CommandFailureException: { "serverUsed" : "localhost:27017" , "createdCollectionAutomatically" : false , "numIndexesBefore" : 2 , "errmsg" : "exception: Index with pattern: { _fts: \"text\ ", _ftsx: 1 } 已经存在不同的选项" , "code" : 85 , "ok" : 0.0}
    • 我修复了这个问题,但我仍然收到原始错误。迁移到 Spring data 1.6.2 解决了这个问题。我错过了什么?
    • 正确的设置。不幸的是,我无法查看您项目设置的所有细节,但我发布的内容基本上是您需要做的。您收到的错误与原始问题无关,而是由索引问题引起的。
    • 正如我提到的,我修复了索引问题,但我仍然收到 isNewStrategy 的原始错误。
    猜你喜欢
    • 2016-03-03
    • 2017-04-05
    • 2017-05-22
    • 1970-01-01
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    • 2016-09-16
    • 1970-01-01
    相关资源
    最近更新 更多