J'ai une entité Hibernate appelée IssueParticipant. Il décrit essentiellement la relation entre un utilisateur et un problème (qui est comme un problème JIRA ou Bugzilla). Il représente une sorte de table de liaison many-to-many dans la base de données, reliant un ID utilisateur à un ID de problème, mais inclut également d'autres informations relatives aux paramètres de notification, et est donc traité comme sa propre entité. J'avais d'énormes problèmes avec l'utilisation de userId et de questionId comme une clé composite, donc j'ai créé une clé synthethic qui est une chaîne (et un varchar dans la base de données postgres), qui est formé comme suit: _.Hibernate saveOrUpdate() essaie d'enregistrer quand il devrait mettre à jour
Maintenant, j'ai un écran où un utilisateur peut éditer tous les utilisateurs associés à un problème, tout en éditant les paramètres de notification. Dans une classe de contrôleur je crée une liste de IssueParticipants comme ceci:
IssueParticipant participant = new IssueParticipant();
participant.setUser(accountUser);
participant.setIssue(issue);
Ce sont bien sûr pas géré par Hibernate à ce stade. Ensuite, dans mon DAO, je les parcourt et appelle saveOrUpdate(), en espérant que si un IssueParticipant ayant la même clé synthétique existe dans la base de données, il sera mis à jour; sinon il sera inséré:
for (IssueParticipant participant : participants) {
getCurrentSession().saveOrUpdate(participant);
savedIds.add(participant.getIssueUserKey());
}
(savedIds est une liste Je maintiens donc que je savoir ce que plus tard IssueParticipants je supprimer de la base de données).
Au lieu de ce que je pense, cependant, je reçois une exception:
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "issue_participant_pkey"
Voici ma classe d'entité, en abrégé:
public class IssueParticipant extends Entity {
private String issueUserKey;
private Long issueId;
private Long userId;
// Edit: adding 'dateAdded' definition
private Date dateAdded;
// ...
// below may be null
private SPUser user;
private Issue issue;
public static IssueParticipant nulledIssueParticipant() {
IssueParticipant ip = new IssueParticipant();
return ip;
}
public String getIssueUserKey() {
return issueUserKey;
}
public void setIssueUserKey(String issueUserKey) {
this.issueUserKey = issueUserKey;
}
public Long getId() {
// currently meaningless
return 0L;
}
public Long getIssueId() {
return this.issueId;
}
public void setIssueId(Long issueId) {
this.issueId = issueId;
updateKey();
}
public Long getUserId() {
return this.userId;
}
public void setUserId(Long userId) {
this.userId = userId;
updateKey();
}
private void updateKey() {
issueUserKey = getIssueId() + KEY_SEP + getUserId();
}
public SPUser getUser() {
return user;
}
public void setUser(SPUser user) {
this.user = user;
setUserId(user.getId());
}
public Issue getIssue() {
return issue;
}
public void setIssue(Issue issue) {
this.issue = issue;
setIssueId(issue.getId());
}
// edit: adding 'dateAdded' methods
public Date getDateAdded() {
return dateAdded;
}
public void setDateAdded(Date dateAdded) {
this.dateAdded = dateAdded;
}
...
}
En voici le fichier HBM:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-lazy="false">
<class name="com.xxx.yyy.IssueParticipant" table="issue_participant">
<id name="issueUserKey" column="issue_user_key" type="string">
<generator class="assigned"/>
</id>
<version name="dateAdded" column="date_added" type="timestamp" unsaved-value="null" />
<property name="issueId" column="issue_id" />
<many-to-one name="user" column="user_id" class="com.xxx.yyy.SPUser" not-null="true" cascade="none" />
<property name="alertRss" column="alert_rss" type="boolean" />
<property name="alertEmail" column="alert_email" type="boolean" />
<property name="alertWeb" column="alert_web" type="boolean" />
<property name="alertClient" column="alert_client" type="boolean" />
</class>
</hibernate-mapping>
Et en effet user_issue_key
est la clé primaire dans la table de base de données correspondante.
Je me sens comme la bonne solution pourrait être d'utiliser SpringJDBC
dans ce cas, mais j'aimerais vraiment comprendre ce qui se passe ici. Quelqu'un a des pensées? Merci d'avance.
Il était une fois que je devais le savoir, puisque j'ai créé le fichier HBM (il doit être proche d'il y a deux ans à ce stade). Quoi qu'il en soit, vous indiquez le rôle de valeur non enregistrée dans dateAdded. Merci! Une fois que j'aurai obtenu plus de points de réputation, ou que je pourrai trouver mes identifiants de connexion précédents, je ferai un pouce de votre réponse. –