繁体   English   中英

无法将 Object 转换为实体类型

[英]Unable to cast the Object to Entity Type

我正在尝试使用 Redis 缓存来提高我们应用程序的性能。 我指的是这篇文章用于我的实现。 我得到了这个例外:

class com.entity.UserEntity cannot be cast to class com.entity.UserEntity

重新配置:

@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<>();
   .
   .
   .
}

UserDaoImpl

@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,因此下一次(在其他会话中)当我们从缓存中检索 Object 时,我们无法将其转换为所需的实体。 有人可以确认这是问题所在,如果是,如何解决?

Hibernate 装饰了 class,这可能是导致问题的原因,另外还有对底层数据库的重量级引用。

我强烈建议(无论您是否使用 Redis)定义您的实体的POJO版本并尽早将实体 class 转换为 POJO,并尽可能地将 POJO 转换为实体,以便您的应用程序处理POJO,并接收、验证和发出(从其 API)POJO,并且该实体在与数据库交互时使用。

将 POJO 实例存储在 Redis 中,而不是实体实例中。

或者为了更健壮,将您的 POJO 序列化为 json 并将 json 字符串存储在 redis 中,在返回的途中对其进行反序列化。 Jackson(随 spring 启动免费提供,开箱即用支持此功能。实现起来超级简单,而且您可以通过目视检查ZE111446745A1825B862F8727AE63BCE4的内容轻松调试 ZE111446745A1825B862F8727AE63BCE4 中的内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM