I have a scenerio where one staff can belong to multiple organisation and for each organisation he can have different role. How can i map this in jpa?
Staff.java
public class Staff {
#ManyToMany
#JoinTable(name="STAFF_ORGANIZATION",joinColumns=#JoinColumn(name="staff_id"),inverseJoinColumns=#JoinColumn(name="organization_id"))
private Set<Organization> organizations;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
}
Organization.java
public class Organization {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column
private String OrganizationName;
#ManyToMany(mappedBy="organizations")
private Set<Staff> staff;
}
StaffRoles.java
public class StaffRoles {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column
#Enumerated(EnumType.ORDINAL)
private Roles roles;
public enum Roles {
USER(100), ADMIN(200);
private int values;
Roles(int values) {
this.values = values;
}
public int getValues() {
return values;
}
}
Can anyone please help me in mapping the roles to the staff. So many staff can belong to many organisation and for each organisation he can have different role.
Any help will be highly appreciated!
Related
Given the following entity classes, examine the possible way to
Create bidirectional One (Student) to One (Account) relationship
Create unidirectional One (Student) to Many (Account) relationship
Here down is Student entity:
#Entity
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private int password;
public Student() {
}
}
Here down is Account entity:
#Entity
public class Account implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private double balance;
public Account() {
}
}
I have the following hierarchy for a football match.
#Entity
public class Match {
#Id
#GeneratedValue
protected Integer id;
#Column(name = "home_team_id")
private int homeTeamId;
#Column(name = "away_team_id")
private int awayTeamId;
private TeamScore homeScore;
private TeamScore awayScore;
}
#Entity(name = "team_score")
public class TeamScore {
#EmbeddedId
protected TeamScoreId id;
private List<Goal> goals;
}
#Embeddable
public class TeamScoreId {
#Column(name = "match_id")
private Integer matchId;
#Column(name = "team_id")
private int teamId;
}
And I have a problem with mapping homeScore and awayScore in Match with TeamScore entity.
The first concern is whether two #OneToOne relations should be here. And how should they be configured?
The second one relates to matchId in TeamScoreId. How this mapping can be performed?
I am working on converting an existing project over to use Hibernate. I have a class like this:
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_id")
private Long userId;
#Column(name = "group_id_user")
private Long groupId;
#Column(name = "name")
private String name;
...
// getters and setters....
}
and a class like this:
#Entity
#Table(name = "group")
public class Group {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "group_id")
private Long groupId;
#Column(name="group_name")
private String groupName;
...
// getters and setters....
}
The column named "group_id_user" in the user table is supposed to be a foreign key to the column named "group_id" in the group table.
Is it okay or "correct" to have the classes structured as shown above or should they be structured as shown below to make sure that the foreign key exists in the Database?
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_id")
private Long userId;
#ManyToOne
#JoinColumn(name = "group_id_user")
private Group group;
#Column(name = "name")
private String name;
...
// getters and setters....
}
and
#Entity
#Table(name = "group")
public class Group {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "group_id")
private Long groupId;
#Column(name="group_name")
private String groupName;
...
// getters and setters....
}
I have tried using both formats but have had issues both ways. When I use the first format I have issues with the HQL syntax for joins while creating queries. When I try the second format I have issues with fetching just a User from the database without a Group, or adding a new User from a json object the has a groupId instead of a Group object. So before I spend anymore time switching back and forth between the two formats I want to know for sure which way should I be using the annotations to best fit industry standard?
I would try something like this if you could change the name of the columns too:
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY) //This means you will need the database to generate the ids, if you are using Oracle this won't work. You would need to use SEQUENCE.
private Long id;
#ManyToOne
#JoinColumn(name = "group_id") //There will be no need to specify the join column if you use group_id.
private Group group;
#Column(name = "name")
private String name;
...
// getters and setters....
}
#Entity
#Table(name = "groups")
public class Group {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name="group_name")
private String groupName;
...
// getters and setters....
}
Also if you can I would change the name of the tables to plural.
Also I use something that helps me a lot. I have a super class called "Identifiable" which just has the id and it looks like this:
#MappedSuperclass
public class Identifiable implements Serializable {
private static final long serialVersionUID = -9027542469937539859L;
#Id
#Column(name = "ID")
#GeneratedValue
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Identifiable other = (Identifiable) obj;
if (id == null) {
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
}
With that you can extend all your classes with ids easily like:
#Entity
#Table(name = "users")
public class User extends Identifiable {
private static final long serialVersionUID = -90275424699375956859L;
#ManyToOne
#JoinColumn(name = "group_id") //There will be no need to specify the join column if you use group_id.
private Group group;
#Column(name = "name")
private String name;
...
// getters and setters....
}
However if you cannot change the names, let us know the issues you are having with the traces that are throwing and we might be able to help.
Thanks!
I have the next relationship:
Currently, I have the next code:
#Embedded
public class StockPK implements Serializable {
private int storeId;
private int productId
}
#Entity
public class Stock implements Serializable {
#EmbeddedId
private StockPK id;
private int cantidad;
#ManyToOne
private Store store;
#ManyToOne
private Product product;
}
But the DDL generated (I'm using OpenJPA in TomEE) adds two aditional fields.
CREATE TABLE STOCK (
productId INTEGER NOT NULL,
storeId INTEGER NOT NULL,
quantity INTEGER NOT NULL,
PRODUCT_ID INTEGER ,
STORE_ID INTEGER ,
PRIMARY KEY (productId, storeId)
)
How should specify this relationship?
Thanks JBNizet :) — The solution was as follows:
#Embeddable
public class StockPK implements Serializable {
#Column(name = "store_id")
private int storeId;
#Column(name = "product_id")
private String productId;
// Getters, setters, hashCode, equals
}
#Entity
#Table(name = "stock")
public class Stock implements Serializable {
#EmbeddedId
private StockPK id;
#MapsId("storeId")
#ManyToOne
private Store store;
#MapsId("productId")
#ManyToOne
private Product product;
#Column(nullable = false)
private int quantity;
// Getters, setters
}
#Entity
#Table(name = "store")
public class Store implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
// Other fields, getters, setters ...
}
#Entity
#Table(name = "product")
public class Product implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
// Other fields, getters, setters ...
}
I have two classes
Alocacao and Responsavel
I have a 1:n
Responsavel.class
#Entity
#Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
#Table(name="Responsavel")
public class Responsavel {
#Id
#Column(name="idResp")
private int idResp;
#Column(name="nomeResp")
private String nomeResp;
#Column(name="emailResp")
private String email;
#ManyToOne(fetch=FetchType.EAGER)
#JoinColumn(name="idGrupResp")
private GrupoResponsavel grupo;
#Column(name="idPovUser")
private int povUser;
#ManyToMany(mappedBy="responsavel", fetch=FetchType.EAGER)
private List<TarefaBackLog> tarefa;
public Responsavel() {
super();
}
//getters and setters
Alocacao.class
#Entity
#Table(name = "responsavel_alocacao")
public class Alocacao {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "idRespAloc")
private int idAlocacao;
#ManyToOne
#JoinColumn(name="idResponsavel", referencedColumnName="idResp")
private Responsavel idResponsavel;
#JoinColumn(name="idPeriodo")
private PeriodoPov idPeriodo;
#Column(name="Alocacao")
private double alocacao;
//getters and setters
But when I try to get all the Alocacao objects with "findAll()", it brings me null values to idPeriodo and idResponsavel.. any ideas?
Thanks