springboot - Spring Boot Redis enregistre l'objet de hachage à l'aide d'un problème d'identification personnalisé
阿神
阿神 2017-05-16 13:20:12
0
1
1703
  1. Informations connexes sur les bottes à ressort utilisées

La version de Spring Boot actuellement utilisée est 1.5.2.RELEASE, 数据库操作使用的是 spring-boot-starter-data-jpa,redis使用的是spring-boot-starter-data-redis

Pour les opérations de base de données, j'utilise le référentiel JPA fourni par Spring Boot et Redis utilise les référentiels Redis.

Un scénario courant consiste à enregistrer des données dans MySQL via JPA. Après succès, mettez à jour l'objet de hachage de Redis.

Selon le document officiel d'introduction des référentiels Spring Data Redis, je dois configurer l'entité.

2.Codes associés

Prenons l'exemple de l'enregistrement d'une commande, transmettez un DTO, appelez la méthode jpa pour écrire dans la base de données et écrivez dans le cache après succès.
Le code principal est le suivant :

Utilisez pour activer la mise en cache dans le fichier principal
@EnableRedisRepositories(basePackages = {"com.test"})
@EnableCaching

@SpringBootApplication
@EnableJpaRepositories(basePackages = {"com.test"})
@EnableRedisRepositories(basePackages = {"com.test"})
@EnableCaching
@EnableJpaAuditing
@EntityScan(basePackages = {"com.test"})
@ComponentScan(basePackages = {"com.test"} )
public class Application {

    private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);

    public static void main(String[] args) {
        final ApplicationContext applicationContext = SpringApplication.run(Application.class, args);
        final String[] activeProfiles = applicationContext.getEnvironment().getActiveProfiles();
        for (String profile : activeProfiles) {
            LOGGER.info("using profile {}", profile);
        }
    }
}

RedisConfig réécrit certaines fonctions de mise en cache

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    @Override
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                System.out.println(sb.toString());
                return sb.toString();
            }
        };
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        cacheManager.setDefaultExpiration(300);
        return cacheManager;
    }
}

OrderService appelle la méthode save pour enregistrer les données dans la base de données. Ce formulaire est utilisé ici@CachePut注解,生成的key的主键是order:100.

    @CachePut(value = "order", key = "#order.id")
    @Override
    public void save(OrderDTO orderDTO) {
        try {
            Order order = BeanMapper.map(orderDTO, Order.class);
            order = orderRepository.save(order);
            System.out.println(order);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Les paramètres des entités sont les suivants. La configuration JPA et la configuration Redis sont utilisées ici. C'est un peu vague et je ne sais pas si c'est correct.

@Entity
@Table(name = "order")
@RedisHash(value = "order")
public class Order {
    private Long id;
    private Long userId;

    @org.springframework.data.annotation.Id
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

Le principal problème que j'ai maintenant est :

1) en

.Order实体配置中,如果我在Id上配置了 redis 的 ID 注解 @org.springframework.data.annotation.Id, 生成的redis key类似这样 order:1222702657038933405, 我想要的效果是生成的key直接使用订单id,类似这样 order:100

J'ai une configuration sur Service

mais elle ne prend pas effet. @CachePut(value = "order", key = "#order.id")

2) Lors du débogage, j'ai constaté que même si l'objet généré a un identifiant, il signalera toujours que l'attribut id de l'expression n'existe pas

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'id' cannot be found on null
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:220) ~[spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:94) ~[spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.accessrrreee0(PropertyOrFieldReference.java:46) ~[spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.expression.spel.ast.PropertyOrFieldReference$AccessorLValue.getValue(PropertyOrFieldReference.java:375) ~[spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88) ~[spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:120) ~[spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:242) ~[spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.cache.interceptor.CacheOperationExpressionEvaluator.key(CacheOperationExpressionEvaluator.java:117) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.generateKey(CacheAspectSupport.java:742) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.cache.interceptor.CacheAspectSupport.generateKey(CacheAspectSupport.java:558) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.cache.interceptor.CacheAspectSupport.collectPutRequests(CacheAspectSupport.java:529) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:413) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:327) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656) ~[spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at com.jiabangou.order.services.impls.OrderServiceImpl$$EnhancerBySpringCGLIB$ceab7f.save(<generated>) ~[classes/:na]
    at com.jiabangou.bops.controllers.api.OrderApiController.save(OrderApiController.java:32) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_65]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_65]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_65]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_65]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    ... 95 common frames omitted

3) Mis à part le problème selon lequel la clé créée par redis est incorrecte, nous avons constaté que l'objet redis peut être enregistré avec succès, mais que l'enregistrement de la base de données n'est pas créé avec succès. Si vous supprimez l'annotation

sur l'entité Order, l'enregistrement de la base de données peut être créé avec succès, mais le cache ne peut pas être créé avec succès. @RedisHash(value = "order")

阿神
阿神

闭关修行中......

répondre à tous(1)
给我你的怀抱

Tout d'abord, la clé doit être le nom de l'attribut

@CachePut(value = "order", key = "#orderDTO.id")

Deuxièmement, @RedisHash est utilisé pour conserver des objets dans Redis. Ce que vous souhaitez utiliser ici, c'est le cache Redis, pas la persistance, cela n'a donc rien à voir avec RedisHash.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!