Tengo una entidad Hibernate llamada IssueParticipant. Básicamente, describe la relación entre un usuario y un problema (que es como un problema JIRA o Bugzilla). Representa un tipo de tabla de vinculación de muchos a muchos en la base de datos, que vincula un ID de usuario con un ID de problema, pero también incluye otra información relacionada con la configuración de notificación, por lo que se trata como su propia entidad.Hibernar saveOrUpdate() intenta guardar cuando debería actualizar
Estaba teniendo grandes problemas con el uso de userId y issueId como una clave compuesta, así que creé una clave sintética que es una cadena (y varchar en la base de datos postgres), que se forma como: _.
Ahora, tengo una pantalla donde un usuario puede editar todos los usuarios asociados con un problema, al mismo tiempo que edita la configuración de notificación. En una clase de controlador de E Crear una lista de IssueParticipants así:
IssueParticipant participant = new IssueParticipant();
participant.setUser(accountUser);
participant.setIssue(issue);
lo que estos son, por supuesto, no se maneja por Hibernate en este punto.
Luego en mi DAO, repito a través de ellos y llamo a saveOrUpdate(), esperando que si existe un IssueParticipant con la misma clave sintética en la base de datos, se actualizará; de lo contrario se inserta:
for (IssueParticipant participant : participants) {
getCurrentSession().saveOrUpdate(participant);
savedIds.add(participant.getIssueUserKey());
}
(savedIds es una lista estoy manteniendo por lo que más adelante voy a saber qué IssueParticipants debería eliminar de la base de datos).
En lugar de lo que cabe esperar, sin embargo, me sale una excepción:
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "issue_participant_pkey"
Aquí está mi clase de entidad, abreviado:
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;
}
...
}
Aquí está su archivo de 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>
Y de hecho user_issue_key
es la clave principal en la tabla de la base de datos correspondiente.
Creo que la solución correcta podría ser utilizar SpringJDBC
en este caso, pero me encantaría descubrir qué está pasando aquí. Alguien tiene alguna idea? Gracias por adelantado.
Érase una vez que debo haber sabido esto, ya que creé el archivo HBM (debe estar cerca de hace dos años en este punto). En cualquier caso, lo que necesitaba era indicar el rol de valor sin guardar en dateAdded; ¡Gracias! Una vez que obtengo más puntos de reputación o puedo encontrar mis credenciales de inicio de sesión anteriores, le daré su respuesta. –