Association n-air : User-role-profil
Salut à tous,
Je débute en EJB3 et j’ai un souci d’implémentation pour la gestion des autorisations. Un user a un role. Un rôle a plusieurs profiles : User[1]-> [1-*] Role [1] -> [1-*]Profil
J’ai donc les classes suivantes :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| @Entity
@Name("user")
@Scope(SESSION)
public class User implements Serializable {
private Long id;
private String firstname;
private String lastname;
private boolean enabled;
private List<Role> roles;
@Id
@GeneratedValue
@Column(name="USER_ID")
public Long getId() {
return id;
}
public void setId(Long userId) {
this.id = userId;
}
@Column(name="USER_FIRSTNAME")
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
@Column(name="USER_LASTNAME")
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
@Column(name="USER_ENABLED")
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@ManyToMany(targetEntity = Role.class)
@JoinTable( name = "AUTHORIZATION_RULES",
joinColumns = @JoinColumn(name = "USER_ID"),
inverseJoinColumns = @JoinColumn(name = "ROLE_ID"))
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
} |
Les Roles :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| @Entity
public class Role implements Serializable {
private Long id;
private String rolename;
private boolean conditional;
private List<Profil> profils;
private List<User> users;
private List<Profil> authorizedProfiles;
@Id
@GeneratedValue
@Column(name="ROLE_ID")
public Long getId() {
return id;
}
public void setId(Long roleId) {
this.id = roleId;
}
public String getRolename() {
return rolename;
}
public void setRolename(String rolename) {
this.rolename = rolename;
}
public boolean isConditional() {
return conditional;
}
public void setConditional(boolean conditional) {
this.conditional = conditional;
}
@ManyToMany(mappedBy="roles")
@JoinTable( name = "AUTHORIZATION_RULES",
joinColumns = @JoinColumn(name = "ROLE_ID"),
inverseJoinColumns = @JoinColumn(name = "USER_ID"))
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
/**
* Relation entre les users, les roles et les profiles
* @return
*/
@ManyToMany(targetEntity = Profil.class)
@JoinTable( name = "AUTHORIZATION_RULES",
joinColumns = @JoinColumn(name = "ROLE_ID"),
inverseJoinColumns = @JoinColumn(name = "PROFIL_ID"))
public List<Profil> getProfils() {
return profils;
}
public void setProfils(List<Profil> profils) {
this.profils = profils;
}
} |
Les profiles :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| @Entity
public class Profil implements Serializable {
private Long id;
private String profilName;
private List<Role> roles;
@ManyToMany(targetEntity=Role.class)
@JoinTable( name = "AUTHORIZATION_RULES",
joinColumns = @JoinColumn(name = "PROFIL_ID"),
inverseJoinColumns = @JoinColumn(name = "ROLE_ID"))
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
@Id
@GeneratedValue
@Column(name="PROFIL_ID")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Length(max = 20)
public String getProfilName() {
return profilName;
}
public void setProfilName(String name) {
this.profilName = name;
}
} |
Dans le session bean, je fais l’update suivant :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public void update(User user) {
Long idUser=user.getId();
//Mise à jour des Roles/Profils : annule et remplace
String sqlQuery = "DELETE FROM AUTHORIZATION_RULES WHERE USER_ID = ?1";
Query deleteQuery = entityManager.createNativeQuery(sqlQuery)
.setParameter(1, user.getId());
int nbUpdate = deleteQuery.executeUpdate();
sqlQuery = "INSERT INTO AUTHORIZATION_RULES (user_id,role_Id,profil_Id) VALUES (?1,?2,?3)";
List<Role>roles = user.getRoles();
for (Role role : roles) {
Long idRole=role.getId();
List<Profil>profils = role.getProfils();
for (Profil profil : profils) {
Long idProfil=profil.getId();
Query insertQuery = entityManager.createNativeQuery(sqlQuery)
.setParameter(1, idUser)
.setParameter(2, idRole)
.setParameter(3, idProfil);
nbUpdate = insertQuery.executeUpdate();
}
}
entityManager.merge(user);
} |
Quand j’execute cette méthode, j’ai l’erreur suivante :
Citation:
22:31:54,968 WARN [JDBCExceptionReporter] SQL Error: 1364, SQLState: HY000
22:31:54,968 ERROR [JDBCExceptionReporter] Field 'PROFIL_ID' doesn't have a default value
22:31:54,968 ERROR [AbstractFlushingEventListener] Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
…
Caused by: java.sql.BatchUpdateException: Field 'PROFIL_ID' doesn't have a default value
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1213)
…
22:31:54,984 WARN [arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator_2] TwoPhaseCoordinator.beforeCompletion - failed for com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple@1bb4422
javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
Est-ce que vous avez une idée ?