如何解决@ManyToMany 关系的 ebean 缓存问题
当我尝试使用 ebean 缓存系统(使用 io.ebean:ebean-redis)基本上读取 @ManyToMany 关系时出现异常。这是一个 SpringBoot 应用程序。
我使用的版本:
- springBootVersion=2.4.3
- mariaDbVersion=2.7.2
- ebeanVersion=12.7.2
- flywayVersion=7.7.0
BaseModel Java 类:
@MappedSuperclass
public abstract class BaseModel extends Model {
@Id
@GeneratedValue
private Long id;
@WhenCreated
@NotNull
private Instant createdAt;
@WhenModified
@NotNull
private Instant updatedAt;
@NotNull
@SoftDelete
private Boolean deleted = false;
protected BaseModel() {
}
// here the getters and setters
}
文章 Java 类:
@Entity
@Table(name = "article")
@Cache
public class DArticle extends BaseModel {
private static final long serialVersionUID = -7120023327129825322L;
@NotNull
@Index
@Length(20)
private String code;
@DbJson
@NotNull
private Map<Locale,String> name;
@NotNull
private Double unitPrice;
@ManyToMany(mappedBy = "articles")
private List<DArticleCategory> articleCategories;
public DArticle(String code,Map<Locale,String> name,Double unitPrice) {
super();
this.code = code;
this.name = name;
this.unitPrice = unitPrice;
}
// here the getters and setters
}
ArticleCategory Java 类:
@Entity
@Table(name = "article_category")
@Cache
public class DArticleCategory extends BaseModel {
private static final long serialVersionUID = 528512691717594544L;
@DbJson
@NotNull
private Map<Locale,String> name;
@ManyToMany
private List<DArticle> articles;
public DArticleCategory(Map<Locale,String> name) {
super();
this.name = name;
}
// here the getters and setters
}
SQL(我使用 flyway 进行迁移):
create table `article` (
`id` bigint auto_increment not null,`created_at` datetime(6) not null,`updated_at` datetime(6) not null,`deleted` tinyint(1) not null,`code` varchar(20) not null,`name` longtext not null,`unit_price` double not null,primary key (`id`),index (`code`)
);
create table `article_category` (
`id` bigint auto_increment not null,primary key (`id`)
);
我尝试执行的代码:
DArticleCategory c = new DArticleCategory(getTranslatedText("Category 1","Catégorie 1",null));
c.save();
DArticleCategory cat = articleCategoryRepository.findById(1l);
for (DArticle article : cat.getArticles()) {
//nothing
}
例外:
Caused by: java.lang.RuntimeException: Failed to decode cache data
at io.ebean.redis.encode.EncodePrefixKey.encode(EncodePrefixKey.java:26)
at io.ebean.redis.RedisCache.key(RedisCache.java:85)
at io.ebean.redis.RedisCache.get(RedisCache.java:139)
at io.ebeaninternal.server.deploy.BeanDescriptorCacheHelp.manyPropGet(BeanDescriptorCacheHelp.java:277)
at io.ebeaninternal.server.deploy.BeanDescriptorCacheHelp.manyPropLoad(BeanDescriptorCacheHelp.java:297)
at io.ebeaninternal.server.deploy.BeanDescriptor.cacheManyPropLoad(BeanDescriptor.java:1306)
at io.ebeaninternal.server.loadcontext.DLoadManyContext$LoadBuffer.loadMany(DLoadManyContext.java:215)
at io.ebean.common.AbstractBeanCollection.lazyLoadCollection(AbstractBeanCollection.java:101)
at io.ebean.common.BeanList.init(BeanList.java:139)
at io.ebean.common.BeanList.iterator(BeanList.java:335)
at db.migration.dev.V2_0_1__katel_test.migrate(V2_0_1__katel_test.java:200)
at org.flywaydb.core.internal.resolver.java.JavaMigrationExecutor.executeOnce(JavaMigrationExecutor.java:61)
... 59 common frames omitted
Caused by: java.lang.IllegalStateException: Expecting String keys but got type:class java.lang.Long
at io.ebean.redis.encode.EncodePrefixKey.encode(EncodePrefixKey.java:19)
... 70 common frames omitted
看起来很简单的代码,但我看不出哪里错了...
解决方法
注解@Cacheable 仅适用于允许拦截器的公共公开方法。但是如果需要,您可以获得“CacheManager”服务并在您的代码中使用它来内部处理私有方法中的缓存。但只是为了解决一些“特殊”问题,通常的方法是对公共方法进行注释。
此外,如果您只使用 starter,那么您只使用了 Spring 的基本和糟糕的实现,一个简单的内存缓存。
考虑您的应用程序将如何工作(单个应用程序、分布式应用程序、缓存的短/长数据量……)以及添加任何支持的缓存管理器(如 ehCache、Hazelcast、Caffeine)的依赖项的内存消耗,...满足您的要求并提高您的缓存性能。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。