[英]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.