My application uses Spring Boot 3.3.7 with JPA support enabled, which means Hibernate 6 is being used.
I need to define the following Java structure to be persisted using Java entity classes:
A
Company
(e.g. 001),can have many users (e.g. [email protected]),
and each
User
can have many applications (e.g. demo),each
Application
will have 1 associatedEmitter
to it, which will basically contain an ID (e.g. 1234-5678).
Here is a tree of the hierarchy:
.
├── 001
│ ├── [email protected]
│ │ └── test
│ │ └── EmitterId (1234-5678)
│ └── [email protected]
│ ├── test
│ │ └── EmitterId (9876-5432)
│ └── demo
│ └── EmitterId (9876-9876)
└── 002
└── [email protected]
└── demo
└── EmitterId (1234-5678)
My goal is to be able to query the database to fetch the Emitter ID by providing 3 pieces of data:
- company (001) +
- user ([email protected]) +
- application (test)
= 1234-5678
If I know these values upfront, I should be able to fetch the associated EmitterId value.
I'm not too familiar with modelling a Map
using JPA and below is my first attempt, but I feel like this is not the right way to go about the problem.
Can anyone provide some insight as to how this could be modeled better?
I'm using Liquibase integration with Hibernate to generate changelog's based on the Entity classes.
I'd like the primary key for Company
to be the keys from the Map
also.
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import java.util.Map;
@Entity
public class Company {
@Id
private String id;
@ElementCollection
private Map<String, User> users;
// getters / setters
}
User.java
:
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import java.util.Map;
@Entity
public class User {
@Id
private String id;
@ElementCollection
private Map<String, Application> applications;
@ManyToOne
private Company company;
// getters / setters
}
Application.java
:
@Entity
public class Application {
@Id
private String id;
@ManyToOne
private User user;
private Emitter emitter;
// getters / setters
}
Emitter.java
:
@Entity
public class Emitter {
@Id
private String id;
// getters / setters
}
My application uses Spring Boot 3.3.7 with JPA support enabled, which means Hibernate 6 is being used.
I need to define the following Java structure to be persisted using Java entity classes:
A
Company
(e.g. 001),can have many users (e.g. [email protected]),
and each
User
can have many applications (e.g. demo),each
Application
will have 1 associatedEmitter
to it, which will basically contain an ID (e.g. 1234-5678).
Here is a tree of the hierarchy:
.
├── 001
│ ├── [email protected]
│ │ └── test
│ │ └── EmitterId (1234-5678)
│ └── [email protected]
│ ├── test
│ │ └── EmitterId (9876-5432)
│ └── demo
│ └── EmitterId (9876-9876)
└── 002
└── [email protected]
└── demo
└── EmitterId (1234-5678)
My goal is to be able to query the database to fetch the Emitter ID by providing 3 pieces of data:
- company (001) +
- user ([email protected]) +
- application (test)
= 1234-5678
If I know these values upfront, I should be able to fetch the associated EmitterId value.
I'm not too familiar with modelling a Map
using JPA and below is my first attempt, but I feel like this is not the right way to go about the problem.
Can anyone provide some insight as to how this could be modeled better?
I'm using Liquibase integration with Hibernate to generate changelog's based on the Entity classes.
I'd like the primary key for Company
to be the keys from the Map
also.
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import java.util.Map;
@Entity
public class Company {
@Id
private String id;
@ElementCollection
private Map<String, User> users;
// getters / setters
}
User.java
:
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import java.util.Map;
@Entity
public class User {
@Id
private String id;
@ElementCollection
private Map<String, Application> applications;
@ManyToOne
private Company company;
// getters / setters
}
Application.java
:
@Entity
public class Application {
@Id
private String id;
@ManyToOne
private User user;
private Emitter emitter;
// getters / setters
}
Emitter.java
:
@Entity
public class Emitter {
@Id
private String id;
// getters / setters
}
Share
Improve this question
edited Jan 29 at 9:19
Mark Rotteveel
109k229 gold badges156 silver badges220 bronze badges
asked Jan 28 at 23:15
bobbyrne01bobbyrne01
6,76322 gold badges84 silver badges168 bronze badges
7
|
Show 2 more comments
1 Answer
Reset to default 0It isn't clear how you want to represent this in the database. Some of your comments suggest that Users have many companies (not a ManyToOne), so I suspect you want a single 'application' to have many users and companies as well:
COMPANY
ID | Name |
---|---|
1 | 001 |
2 | 002 |
USER
ID | Name |
---|---|
1 | [email protected] |
2 | [email protected] |
APPLICATION
ID | Name |
---|---|
1 | test |
2 | demo |
EMITTER
ID |
---|
1234-5678 |
9876-5432 |
9876-9876 |
To join them all up, you need a separate table:
EMITTER_RELATIONS
EMITTER_ID | USER_ID | COMPANY_ID | APP_ID |
---|---|---|---|
1234-5678 | 2 | 1 | 1 |
9876-5432 | 1 | 1 | 1 |
9876-9876 | 1 | 1 | 2 |
1234-5678 | 1 | 2 | 2 |
You can use generated IDs like I have above, or the user, company, application name fields as the ID instead to make it easier if you want. I prefer generated IDs overall, though querying using the names will require joins - so its up to you.
Using the names as IDs though, I'd model this as:
@Entity
public class User {
@Id
private String id;
@OneToMany(mappedBy="user")
private List<EmmitterRelation> emitterRelations;
}
@Entity
public class Application {
@Id
private String id;
@OneToMany(mappedBy="app")
private List<EmmitterRelation> emitterRelations;
}
@Entity
public class Company {
@Id
private String id;
@OneToMany(mappedBy="company")
private List<EmmitterRelation> emitterRelations;
}
@Entity
public class Emitter {
@Id
private String id;
@OneToMany(mappedBy="emitter")
private List<EmmitterRelation> emitterRelations;
}
public class EmitterRelationID {
public String company;
private String user;
private String app;
}
@Entity
@Table(name = "EMITTER_RELATION")
@IdClass(EmitterRelationID.class)
public class EmitterRelation {
@Id
@ManyToOne
private Company company;
@Id
@ManyToOne
private User user;
@Id
@ManyToOne
private Application app;
@ManyToOne
private Emitter emitter;
}
test
anddemo
have the same EmitterId ((1234-5678
))? – life888888 Commented Jan 29 at 1:30company
+user
+application
.. once they know the Emitter ID, they can check their in-memory data structure to see if they have the right Emitter instance – bobbyrne01 Commented Jan 29 at 8:25User
can belong to 1 or moreCompany
. Same applies forApplication
, it can be associated with 1 or moreUser
– bobbyrne01 Commented Jan 29 at 23:18