I'm starting with hibernate and I having some difficulties to build a easy
relationship of tables
, hibernate throw nested exception is org.hibernate.MappingException: Unable to find column with logical name: USERNAME in org.hibernate.mapping.Table(USER_FILESYSTEM) and its related supertables and secondary tables
I have this model
USER--1---N-->USER_FILE_SYSTEM--1--N-->USER_FS_THUMBS
All column name on DB squema are OK the column username" exists on table USER_FILESYSTEM
and table user
Table Users
#Entity
#Table(name = "USERS")
public class Users implements Serializable {
#Id
#Column(name = "USERNAME", nullable = false, length = 15)
private String username;
#Column(name = "PASSWORD", nullable = false, length = 64)
private String password;
#Column(name = "FIRSTNAME", length = 32)
private String firstname;
#Column(name = "LASTNAME", length = 32)
private String lastname;
#Column(name = "EMAIL", nullable = false, length = 60)
private String email;
#Column(name = "TELEPHONE", length = 50)
private String telephone;
#OneToOne(cascade = CascadeType.ALL)
#JoinTable(name = "USER_ROLE",
joinColumns = {
#JoinColumn(name = "USERNAME_ID", referencedColumnName = "USERNAME")},
inverseJoinColumns = {
#JoinColumn(name = "ROL_ID", referencedColumnName = "ROL")}
)
private Rol role;
#OneToMany(
fetch = FetchType.EAGER, mappedBy = "username"
)
private Set<UserFileSystem> fileSystem;
Table UserFileSystem
#Entity
#Table(name = "USER_FILESYSTEM")
public class UserFileSystem implements Serializable {
#Id
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "USERNAME", nullable = false)
private Users username;
#Id
#Column(name = "SERVICE_ID", nullable = false, length = 10)
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer serviceId;
#Id
#Column(name = "SERVICE_FOLDER", nullable = false, length = 64)
private String serviceFolder;
#Column(name = "PROTOCOL", length = 20)
private String protocol;
#Column(name = "PARAMS", length = 512)
private String params;
#OneToMany(
fetch = FetchType.LAZY, mappedBy = "userFileSystemThumbsPK"
)
private Set<UserFileSystemThumbs> fileSystemThumbs;
Table UserFileSystemThumbs
#Entity
#Table(name = "USER_FS_THUMBS")
public class UserFileSystemThumbs implements Serializable {
#EmbeddedId
private UserFileSystemThumbsPK userFileSystemThumbsPK;
#Column(name = "SERVICE_URL", nullable = false)
private String serviceUrl;
#Column(name = "CONTENT", nullable = false)
private byte[] content;
#Column(name = "MIME_TYPE", nullable = false)
private String mimeType;
Primary key entity UserFileSystemThumbs
#Embeddable
public class UserFileSystemThumbsPK implements Serializable {
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumns({
#JoinColumn(name = "USERNAME", nullable = false, referencedColumnName = "USERNAME"),
#JoinColumn(name = "SERVICE_ID", nullable = false, referencedColumnName = "SERVICE_ID")
})
private UserFileSystem userFileSystem;
#Column(name = "SERVICE_URL_HASH", nullable = false)
private String serviceUrlHash;
Constructor equals hash....
the problem I think that UserFileSystemThumbsPK USERNAME column do reference to UserFileSystem but in this table the column USERNAME is provided by users.
Solution by OP.
I changed
#Entity
#Table(name = "USER_FILESYSTEM")
public class UserFileSystem implements Serializable {
#Id
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "USERNAME", nullable = false)
private Users username;
#Id
#Column(name = "SERVICE_ID", nullable = false, length = 10)
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer serviceId;
}
for this
#Entity
#Table(name = "USER_FILESYSTEM")
public class UserFileSystem implements Serializable {
#EmbeddedId
private UserFileSystemID userFSID;
}
and I created the object UserFileSystemID with 2 values of PK
It's working like a champ!
Related
I have to join two tables with ManyToOne relationship using JPA.
TABLE 1 -> manF
#Entity
#Table(name = "manf")
public class ManF {
#EmbeddedId
private ManFCompositeKey manFCompositeKey;
#Column(name = "name", length = 10)
private String manFName;
#Column(name = "desc", length = 150)
private String manFDesc;
}
#Embeddable
public class ManFCompositeKey {
#Column(name = "man_code", length = 20, nullable = false)
private String manCode;
#Column(name = "update_time", nullable = false)
private Date updTime;
}
TABLE 2 -> products
#Entity
#Table(name = "products")
public class Prod {
#EmbeddedId
private ProdCompositeKey prodCompositeKey;
#Column(name = "name", length = 10)
private String prodName;
#Column(name = "prod_desc", length = 150)
private String prodDesc;
// -> JoinColumn here.
#Column(name = "man_code", length = 20, nullable = false)
private String manCode;
}
#Embeddable
public class ProdCompositeKey {
#Column(name = "prod_code", length = 20, nullable = false)
private String prodCode;
#Column(name = "update_time", nullable = false)
private Date updTime;
}
Now, manF(Table 1) can have many products(Table 2). Thus, for each row in product table, there can be same manFCode.
I intend to establish a join b/w T1 and T2 such that manCode column in products behaves as the FK for this table referenceing man_code of Table 1.
Below is the join condition I wrote:
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumns({
#JoinColumn(name = "man_code", referencedColumnName = "man_code")
})
#Column(name = "man_code", length = 20, nullable = false)
private ManF manF;
This should make sense(I thought), but threw an error, stating: ManF not mapped to a single property.
Now I can do this:
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumns({
#JoinColumn(name = "man_code", referencedColumnName = "man_code")
#JoinColumn(name = "update_time", referencedColumnName = "update_time")
})
#Column(name = "man_code", length = 20, nullable = false)
private ManF manF;
But then I would be keeping a FK reference on the time, on which a ManF was inserted.
I need to know how can I join the two tables here such that I can create a FK reference on the man_code of ManF table and the man_code in the product (child) table.
You can use hibernate native query and write the join condition. If that is not a option I would particularly change the embeddedId on Manf to a regular id and create a constraint in your db, to maintain integrity an use a regular joincolumn condition. Like this:
SQL: ALTER TABLE 'manf' ADD UNIQUE 'UNIQUE_CONSTRAINT'('man_code', 'update_time');
#Entity
#Table(name = "manf")
public class ManF {
#Id
#SequenceGenerator(name = "SEQUENCE_NAME", sequenceName = "SEQUENCE_NAME", allocationSize = 1, initialValue = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQUENCE_NAME")
#Column(name = "man_code", length = 20, nullable = false)
private String manCode;
#Column(name = "update_time", nullable = false)
private Date updTime;
#Column(name = "name", length = 10)
private String manFName;
#Column(name = "desc", length = 150)
private String manFDesc;
}
#Entity
#Table(name = "products")
public class Prod {
#EmbeddedId
private ProdCompositeKey prodCompositeKey;
#Column(name = "name", length = 10)
private String prodName;
#Column(name = "prod_desc", length = 150)
private String prodDesc;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "man_code")
private ManF manF;
}
This is what I have done, to achieve this. May be a hack.
I have put the man_code from from Table 1 (ManF), in the main class (it stays is the Embeddable as well). But in the ManF class I did something like this:
#Entity
#Table(name = "manf")
public class ManF {
#EmbeddedId
private ManFCompositeKey manFCompositeKey;
*#Column(name = "man_code", insertable = false, updatable= false)
private String manCode;*
#Column(name = "name", length = 10)
private String manFName;
#Column(name = "desc", length = 150)
private String manFDesc;
}
#Embeddable
public class ManFCompositeKey {
#Column(name = "man_code", length = 20, nullable = false)
private String manCode;
#Column(name = "update_time", nullable = false)
private Date updTime;
}
On the other hand, I have changed my Table 2 as follows:
#Entity
#Table(name = "products")
public class Prod {
#EmbeddedId
private ProdCompositeKey prodCompositeKey;
#Column(name = "name", length = 10)
private String prodName;
#Column(name = "prod_desc", length = 150)
private String prodDesc;
*#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumns({
#JoinColumn(name = "man_code", referencedColumnName =
"man_code")})
private ManF manF;*
*#Column(name = "man_code", insertable = false, updatable = false)
private String manCode;*
#Column(name = "man_code", length = 20, nullable = false)
private String manCode;
}
#Embeddable
public class ProdCompositeKey {
#Column(name = "prod_code", length = 20, nullable = false)
private String prodCode;
#Column(name = "update_time", nullable = false)
private Date updTime;
}
This is somehow working, but I have had to add a new variable in the Child table (here: manCode with insertable and updatabale as false)
I am not sure if this is the correct approach. Please, let me know if someone has a better and elegant idea to approach this issue.
I have these entities:
Run entity:
#Entity
#Table(name = "run")
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
property = "runId")
public class Run implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "run_id")
private Long runId;
#Column(name = "status")
private Integer status;
#Column(name = "create_date")
private Date date;
#Column(name = "config_id")
private Long configId;
#Column(name = "stream_id")
private Long streamId;
#OneToOne(mappedBy = "run", cascade = CascadeType.ALL, orphanRemoval = true)
#JoinColumn(name = "run_id", unique = true, nullable = true, insertable = true, updatable = true)
private StreamRun streamRun;
...
}
and StreamRun entity:
#Entity
#Table(name = "stream_run")
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
property = "streamId")
public class StreamRun implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#Column(name = "id")
private Long streamId;
#Column(name = "run_id", insertable = false, updatable = false)
private Long runId;
#Column(name = "stream_name")
private String streamName;
#OneToOne
#JoinColumn(name = "run_id")
private Run run;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "stream", orphanRemoval = true, targetEntity = JobRun.class)
private List<JobRun> jobs = new ArrayList<>();
#OneToMany(cascade = CascadeType.ALL, mappedBy = "streamRun", orphanRemoval = true, targetEntity = StreamEvent.class)
private List<StreamEvent> events = new ArrayList<>();
....
}
and JobRun entity:
#Entity
#Table(name = "jobs_run")
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
#IdClass(JobRunKey.class)
public class JobRun implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#Column(name = "id")
private Long id;
#Id
#Column(name = "run_id", insertable = false, updatable = false)
private Long runId;
#Column(name = "name")
private String name;
#Column(name = "type")
private String jobType;
#Column(name = "script")
private String script;
#Column(name = "status")
private Integer status;
#ManyToOne
#JoinColumns({ #JoinColumn(name = "run_id", referencedColumnName = "run_id"), #JoinColumn(name = "job_stream_id", referencedColumnName = "id") })
private StreamRun stream;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "jobRun", orphanRemoval = true, targetEntity = JobDependencyRun.class)
public List<JobDependencyRun> dependencies = new ArrayList<>();
#OneToMany(cascade = CascadeType.ALL, mappedBy = "jobRun", orphanRemoval = true, targetEntity = JobEvent.class)
public List<JobEvent> events = new ArrayList<>();
....
}
And all the columns are defined in the MySQL database, Table job_run have composite key of (id and run_id).
The problem is in JobRun entity:
If I define "run_id" field as #ID then an exception appear (when insert)
Parameter index out of range (8 > number of parameters, which is 7).
If I define it without #ID then an exception appear (when update)
Duplicate entry '4-78' for key 'PRIMARY'
If I remove the whole field definition from entity since it is foreign key then the exception will be:
Unable to find column with logical name run_id
"Although the column exists in the table".
Please, can anyone help me?
Do I do anything wrong in the code?
I have managed to find a solution, by modifying JobRun entity as below, and change\access the value of runId from direct setter and getter method.
#Entity
#Table(name = "jobs_run")
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
#IdClass(JobRunKey.class)
public class JobRun implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "id")
private Long id;
#Id
#Column(name = "run_id")
private Long runId;
#Column(name = "job_stream_id")
private Long streamId;
#Column(name = "name")
private String name;
#Column(name = "type")
private String jobType;
#Column(name = "script")
private String script;
#Column(name = "status")
private Integer status;
#ManyToOne
#JoinColumns({ #JoinColumn(name = "run_id", referencedColumnName = "run_id", insertable = false, updatable = false),
#JoinColumn(name = "job_stream_id", referencedColumnName = "id", insertable = false, updatable = false) })
private StreamRun stream;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "jobRun", orphanRemoval = true, targetEntity = JobDependencyRun.class)
public List<JobDependencyRun> dependencies = new ArrayList<>();
#OneToMany(cascade = CascadeType.ALL, mappedBy = "jobRun", orphanRemoval = true, targetEntity = JobEvent.class)
public List<JobEvent> events = new ArrayList<>();
...
}
i have a weird issue : i'am trying to save a User in my DB, this user has a list of skills. those skills are already in the db with linked categories and categories have linked domains. the structure looks like this :
when i print the list of skills from the applicant i have this :
skills=[Skill{categories=[Category{domains=[Domain{id=4, name=DevOps}], id=13, name=BackEnd}], id=23, name=Java}, Skill{categories=[Category{domains=[Domain{id=4, name=DevOps}], id=13, name=BackEnd}], id=24, name=C}],
and here is the table making the link between Applicant and skills :
but when i'm trying to save the applicant i have this Détail : Failing row contains (23, null, null, 499). can someone explain me ? I'm working on a spring application using jpa annotaions.
EDIT 1 :
ApplicantEntity :
#Entity
#Table(name = "ATS_APPLICANT")
public class ApplicantEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "home", unique = false, nullable = true)
private Boolean home;
#Column(name = "anonymous", unique = false, nullable = true)
private Boolean anonymous;
#Enumerated(EnumType.STRING)
#Column(name = "job_type")
private JobType jobType;
#Column(name = "min_salary", unique = false, nullable = true)
private Integer minSalary;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(unique = true)
private UserEntity user;
#OneToMany(targetEntity = ApplicantWorkExperienceEntity.class, cascade = CascadeType.ALL)
private List<ApplicantWorkExperienceEntity> applicantWorkExperiences = new ArrayList<ApplicantWorkExperienceEntity>();
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
#JoinTable(name = "ATS_APPLICANT_SKILL", joinColumns = #JoinColumn(name = "applicant_id", referencedColumnName = "id"), inverseJoinColumns = #JoinColumn(name = "skill_id", referencedColumnName = "id"))
private List<SkillEntity> skills = new ArrayList<SkillEntity>();
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "ATS_APPLICANT_LOCATION", joinColumns = #JoinColumn(name = "applicant_id", referencedColumnName = "id"), inverseJoinColumns = #JoinColumn(name = "location_id", referencedColumnName = "id"))
private List<LocationEntity> locations = new ArrayList<LocationEntity>();
SkillEntity :
#Entity
#Table(name = "ATS_SKILL")
public class SkillEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotNull
#Size(min = 1, max = 42)
#Column(name = "name", length = 42, nullable = false, unique = true)
private String name;
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(name = "ATS_SKILL_CATEGORY", joinColumns = #JoinColumn(name = "skill_id", referencedColumnName = "id"), inverseJoinColumns = #JoinColumn(name = "category_id", referencedColumnName = "id"))
private List<CategoryEntity> categories = new ArrayList<CategoryEntity>();
CategoryEntity :
#Entity
#Table(name = "ATS_CATEGORY")
public class CategoryEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotNull
#Size(min = 1, max = 42)
#Column(name = "name", length = 42, nullable = false, unique = true)
private String name;
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(name = "ATS_CATEGORY_DOMAIN", joinColumns = #JoinColumn(name = "category_id", referencedColumnName = "id"), inverseJoinColumns = #JoinColumn(name = "domain_id", referencedColumnName = "id"))
private List<DomainEntity> domains = new ArrayList<DomainEntity>();
EDIT 2 :
DomainEntity :
#Entity
#Table(name = "ATS_DOMAIN")
public class DomainEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotNull
#Size(min = 1, max = 42)
#Column(name = "name", length = 42, nullable = false, unique = true)
private String name;
I succeed by using #ElementCollection annotation on skills.
I'm using EJB 3 and JPA 2 in my application, i have 2 entities with many to relationship and want to persist them but fortunately after hours of searshing and trying i can't do it, so this is my code:
#Entity
public class Destinataire implements Serializable {
#Id
#Basic(optional = false)
#Size(min = 1, max = 50)
#Column(name = "ADRESSE")
private String adresse;
#OneToMany(mappedBy = "destinataire")
private Set<Envois> envoisSet;
//getters and setters
}
#Entity
public class Envois implements Serializable {
#EmbeddedId
protected EnvoisPK envoisPK = new EnvoisPK();
#Size(max = 4)
#Column(name = "TYPENVOIS")
private String typenvois;
#JoinColumn(name = "IDMAIL", referencedColumnName = "IDMAIL", insertable = false, updatable = false)
#ManyToOne(optional = false)
private MailAEnvoyer mailAEnvoyer;
#JoinColumn(name = "ADRESSE", referencedColumnName = "ADRESSE", insertable = false, updatable = false)
#ManyToOne(optional = false)
private Destinataire destinataire;
}
#Embeddable
public class EnvoisPK implements Serializable {
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 255)
#Column(name = "ADRESSE")
private String adresse;
#Basic(optional = false)
#NotNull
#Column(name = "IDMAIL")
private BigDecimal idmail;
}
#Entity
#Table(name = "MAILAENVOYER")
public class MailAEnvoyer implements Serializable {
private static final long serialVersionUID = 1L;
// #Max(value=?) #Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
#Id
#Basic(optional = false)
#GeneratedValue(strategy = GenerationType.SEQUENCE)
#Column(name = "IDMAIL")
private BigDecimal idmail;
#JoinTable(name = "ENVOIS", joinColumns = {
#JoinColumn(name = "IDMAIL", referencedColumnName = "IDMAIL")}, inverseJoinColumns = {
#JoinColumn(name = "ADRESSE", referencedColumnName = "ADRESSE")})
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
private Set<Destinataire> destinataireSet;
#OneToMany(mappedBy = "mailAEnvoyer", cascade = CascadeType.ALL)
private Set<Envois> envoisSet;
}
this is how i'm proceed :
Envois e = new Envois("CCI");
Destinataire dest = new Destinataire("adress");
destinataireService.create(dest);
e.setDestinataire(dest);
currentMailAEnvoyer.getEnvoisSet().add(e);
mailService.save(currentMailAEnvoyer);
but always i get an exception that EnvoisPK have adresse and idmail null,
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into ("MAILING"."ENVOIS"."IDMAIL")
Error Code: 1400
Call: INSERT INTO ENVOIS (TYPENVOIS, IDMAIL, ADRESSE) VALUES (?, ?, ?)
bind => [3 parameters bound]
Query: InsertObjectQuery(entities.Envois[ envoisPK=entities.EnvoisPK[ adresse=null, idmail=null ] ])
you can add in the entity MailAEnvoyer the method below:
#PostPersist
public void postPersist() {
for (Envois e : envoisSet) {
e.getEnvoisPK().setIdmail(this.getIdmail());
}
}
Would it be possible to declare a HashMap in the following object called Group?
Doing something like this doesn't work:
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "group")
#MapKey(name = "member.name")
private Map<String, GroupMember> groupMembers = new HashMap<String, GroupMember>();
StackTrace:
12:07:51 [INFO] [Groups] Enabling Groups v0.1
12:07:51 [SEVERE] Error occurred while enabling Groups v0.1 (Is it up to date?)
java.lang.RuntimeException: An exception has occured while initializing the database
at groups.storage.MyDatabase.initializeDatabase(MyDatabase.java:83)
at groups.storage.Dao.<init>(Dao.java:26)
at groups.Groups.onEnable(Groups.java:30)
at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:217)
at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:457)
at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:381)
at org.bukkit.craftbukkit.v1_5_R2.CraftServer.loadPlugin(CraftServer.java:282)
at org.bukkit.craftbukkit.v1_5_R2.CraftServer.enablePlugins(CraftServer.java:264)
at org.bukkit.craftbukkit.v1_5_R2.CraftServer.reload(CraftServer.java:605)
at org.bukkit.Bukkit.reload(Bukkit.java:184)
at org.bukkit.command.defaults.ReloadCommand.execute(ReloadCommand.java:23)
at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:188)
at org.bukkit.craftbukkit.v1_5_R2.CraftServer.dispatchCommand(CraftServer.java:523)
at org.bukkit.craftbukkit.v1_5_R2.CraftServer.dispatchServerCommand(CraftServer.java:512)
at net.minecraft.server.v1_5_R2.DedicatedServer.am(DedicatedServer.java:261)
at net.minecraft.server.v1_5_R2.DedicatedServer.r(DedicatedServer.java:226)
at net.minecraft.server.v1_5_R2.MinecraftServer.q(MinecraftServer.java:474)
at net.minecraft.server.v1_5_R2.MinecraftServer.run(MinecraftServer.java:407)
at net.minecraft.server.v1_5_R2.ThreadServerApplication.run(SourceFile:573)
Caused by: java.lang.RuntimeException: Failed to create a new instance of the EbeanServer
at groups.storage.MyDatabase.loadDatabase(MyDatabase.java:162)
at groups.storage.MyDatabase.initializeDatabase(MyDatabase.java:77)
... 18 more
Caused by: javax.persistence.PersistenceException: groups.model.Group: Could not find mapKey property [member.name] on [groups.model.GroupMember]
at com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany.initMapKeyProperty(BeanPropertyAssocMany.java:744)
at com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany.initialise(BeanPropertyAssocMany.java:147)
at com.avaje.ebeaninternal.server.deploy.BeanDescriptor.initialiseOther(BeanDescriptor.java:763)
at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.initialiseAll(BeanDescriptorManager.java:403)
at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.deploy(BeanDescriptorManager.java:293)
at com.avaje.ebeaninternal.server.core.InternalConfiguration.<init>(InternalConfiguration.java:150)
at com.avaje.ebeaninternal.server.core.DefaultServerFactory.createServer(DefaultServerFactory.java:209)
at com.avaje.ebeaninternal.server.core.DefaultServerFactory.createServer(DefaultServerFactory.java:64)
at com.avaje.ebean.EbeanServerFactory.create(EbeanServerFactory.java:78)
at groups.storage.MyDatabase.loadDatabase(MyDatabase.java:159)
... 19 more
...
#Entity
#Table(name = "groups_group")
public class Group {
public enum Type {
Include,
Exclude
}
#Id
#GeneratedValue
#Column(name = "id", unique = true, nullable = false)
private Integer id;
#Column(name = "name", unique = true, nullable = false, length = 25)
private String name;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "group")
#MapKey(name = "member.name")
private Map<String, GroupMember> groupMembers = new HashMap<String, GroupMember>();
#Column(name = "personal", nullable = false)
private Boolean personal = false;
#Enumerated(value = EnumType.ORDINAL)
#Column(name = "type", nullable = false, length = 2)
private Type type = Type.Include;
#Column(name = "password", nullable = true, length = 16)
private String password;
#Version
#Column(name = "update_time", nullable = false)
Timestamp updatetime;
#CreatedTimestamp
#Column(name = "create_time", nullable = false)
Timestamp createTime;
public Group() {}
//getters and setters
}
..
#Entity
#Table(name = "groups_group_member")
public class GroupMember {
public enum Role {
ADMIN,
MODERATOR,
MEMBER,
BANNED
}
#Id
#GeneratedValue
#Column(name = "id", unique = true, nullable = false)
private Integer id;
#ManyToOne
#JoinColumn(name = "group_id")
private Group group;
#ManyToOne
#JoinColumn(name = "member_id")
private Member member;
#Enumerated(value = EnumType.ORDINAL)
#Column(name = "role", nullable = false, length = 2)
private Role role = Role.MEMBER;
#Version
#Column(name = "update_time", nullable = false)
Timestamp updatetime;
#CreatedTimestamp
#Column(name = "create_time", nullable = false)
Timestamp createTime;
public GroupMember() {}
//getters and setters...
}
...
#Entity
#Table(name = "groups_member")
public class Member {
#Id
#GeneratedValue
#Column(name = "id", unique = true, nullable = false)
private Integer id;
#Column(name = "name", unique = true, nullable = false, length = 16)
private String name;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "member")
private Set<GroupMember> groupMembers = new HashSet<GroupMember>();
#Version
#Column(name = "update_time", nullable = false)
Timestamp updatetime;
#CreatedTimestamp
#Column(name = "create_time", nullable = false)
Timestamp createTime;
public Member() {}
//getters and setters
}