当我尝试使用 ebean 缓存系统(使用 io.ebean:ebean-redis)基本上读取 @ManyToMany 关系时出现异常。这是一个 SpringBoot 应用程序。
我使用的版本:
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,
`created_at` datetime(6) not null,
`updated_at` datetime(6) not null,
`deleted` tinyint(1) not null,
`name` longtext 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
看起来很简单的代码,但我看不出哪里错了...
答案 0 :(得分:0)
注解@Cacheable 仅适用于允许拦截器的公共公开方法。但是如果需要,您可以获得“CacheManager”服务并在您的代码中使用它来内部处理私有方法中的缓存。但只是为了解决一些“特殊”问题,通常的方法是对公共方法进行注释。
此外,如果您只使用 starter,那么您只使用了 Spring 的基本和糟糕的实现,一个简单的内存缓存。
考虑您的应用程序将如何工作(单个应用程序、分布式应用程序、缓存的短/长数据量……)以及添加任何支持的缓存管理器(如 ehCache、Hazelcast、Caffeine)的依赖项的内存消耗,...满足您的要求并提高您的缓存性能。