java - 无法将对象转换为实体类型

标签 java spring-boot hibernate redis

我正在尝试使用 Redis 缓存来提高我们应用程序的性能。我指的是这个 article对于我的实现。我收到此异常:

class com.entity.UserEntity cannot be cast to class com.entity.UserEntity
Redis配置:
@Configuration
@EnableCaching
public class RedisConfig {

    @Value("${spring.redis.port}") int redisPort;
    @Value("${spring.redis.host}") String redisHost;

    @Bean
    public LettuceConnectionFactory redisLettuceConnectionFactory() {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(redisHost,redisPort);
        return new LettuceConnectionFactory(redisStandaloneConfiguration);
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisLettuceConnectionFactory());

        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setEnableTransactionSupport(true);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}
用户实体:
@Entity
@Getter
@Setter
@EqualsAndHashCode(callSuper=false)
@Slf4j
@Table(name="user")
public class UserEntity extends BaseEntity implements Serializable {
    
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "user_id")
    @Type(type = "uuid-char")
    private UUID userId;//Binary in DB and UUID here

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "user", orphanRemoval = true, cascade= CascadeType.ALL)
    @JsonIgnore
    @ToStringExclude
    @Fetch(value = FetchMode.SUBSELECT)
    private List<EmailAddress> emailAddresses = new ArrayList<>();
   .
   .
   .
}
用户道Impl
@Repository
public class UserDaoImpl implements UserDao {

    private UserRepository userRepository;
    private HashOperations hashOperations; //to access Redis cache
    private static final String KEY = "User";

    public UserDaoImpl(@Autowired RedisTemplate<String, Object> redisTemplate, @Autowired UserRepository userRepository) {
        this.userRepository = userRepository;
        hashOperations = redisTemplate.opsForHash();
    }

    @Override
    public Optional<UserEntity> fetchUserById(String userId) throws Exception {
        
// Getting Exception here (UserEntity) hashOperations.get(KEY,userId)
        UserEntity userEntity = (UserEntity) hashOperations.get(KEY,userId);
        Optional<UserEntity> userOptional = Optional.ofNullable(userEntity);
        if(!userOptional.isPresent()) {
            userOptional = userRepository.findByUserId(userId);
            if (userOptional.isPresent()) {
                System.out.println("Cache Miss User id:" + userOptional.get().getUserId());
                
                hashOperations.put(KEY, userOptional.get().getUserId().toString(), userOptional.get());
            } else {
                throw new Exception("User not present");
            }
        }
        return userOptional;
    }
}

我能够成功地将 UserEntity 放入缓存中,但是在检索时我得到了上面提到的异常。最有可能的问题是由于 Hibernate。当我们第一次缓存实体时,它会用 Proxy/PersistentBag 代替 Collections,所以下次(在其他 session 中)当我们从缓存中检索对象时,我们无法将其转换为所需的实体。有人可以确认这是问题所在,如果是,如何解决?

最佳答案

Hibernate 装饰了类,这可能是导致问题的原因,另外还有对底层数据库的重量级引用。
我强烈建议(无论您是否使用 Redis)定义一个 POJO实体的版本并尽早将实体类转换为 POJO,并尽可能晚地将 POJO 转换为实体,以便您的应用程序处理 POJO,并接收、验证和发出(从其 API)POJO,以及该实体仅在与数据库交互时使用。
在 Redis 中存储 POJO 实例而不是实体实例。
或者为了更健壮,将您的 POJO 序列化为 json 并将 json 字符串存储在 redis 中,在返回的途中将其反序列化。 Jackson(与 spring boot 一起免费提供,支持开箱即用。实现起来 super 简单,而且您可以通过目视检查内容轻松调试 Redis 中的内容。

关于java - 无法将对象转换为实体类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70297666/

相关文章:

java - 将 ByteBuffer 的一部分转换为字符串

java - 如何有条件地将 Transform 应用于 PCollection?

java - 使用 WireMock 测试 Spring JUnit 中的多个应用程序上下文

mysql - 如何配置一个spring+hibernate+mysql项目?

java - 是否可以多次注册单个 Hibernate 拦截器?

java - 使用 Xuggler 进行音频转换

java - OpenCV 在 System.loadLibrary() 上因 SIGSEGV 崩溃;

spring - 如何在 AWS ElasticBeanstalk 和 Nginx 上使用 OAuth2 的 Spring Boot 应用程序上强制使用 SSL?

spring-boot - 如何覆盖jhipster使用的spring boot版本

java - Hibernate - 使用 ScrollMode.FORWARD_ONLY 获取 ScrollableResults 的最后一个元素