I'm trying to load data with the help of Fixtures.loadModels() during application start (@OnApplicationStart) My data file is quite simple, but I'm continuously getting error about duplicate id. However, there is no duplicate id at all.
Category(auto):
idEng: "auto"
title: "Auto"
Group(crossover):
idEng: 开发者_运维技巧"crossover"
title: "Crossovers"
parentCategory: auto
The corresponding classes are:
@Entity
public class Category extends Model {
public String idEng;
public String title;
@OneToOne
public Category parentCategory;
}
@Entity
@Table(name="ItemGroup")
public class Group extends Model {
@Column(length=64)
public String idEng;
@Column(length=64)
public String title;
@ManyToOne
public Category parentCategory;
}
Sometimes it works for just after I start play, but definitely brokes for the second time to load data. I get error:
RuntimeException occured : Cannot load fixture categories.yml:
Cannot load fixture categories.yml, duplicate id 'auto' for type models.Category
Does anyone know what is wrong here? Has anyone faced such problem before?
I debugged it a bit and found the reason: Play caches ids of loaded entities in Fixtures.idCache. So on the first time after startup it works fine because the cache is empty. However, when Play recreates databases and try to load data second time, the cache already contains the given ids and Play throws the exception. It happens on the following piece of code (Fixtures.loadModels(String name), lines 185-187):
if (idCache.containsKey(type + "-" + id)) {
throw new RuntimeException("Cannot load fixture " + name + ", duplicate id '" + id + "' for type " + type);
}
To clear cache it is necessary to call Fixtures.delete() or Fixtures.deleteDatabase(). These methods clear idCache variable.
To resolve my problem I just added call of Fixtures.delete() just before Fixtures.loadModels()
I can't test it right now, but I would say that the problem is the @OneToOne annotation. It will expect the target class to have the reverse mapping, and in this case it doesn't exist. You should be able to add a new attribute that manages the mapping for the other end of the relation, here you can find more detail
Also, are you sure you want a @OneToOne rel, not a @OneToMany? I can't see how a category can only have one parent and one child, not one parent and many children...
精彩评论