Bonjour à tous,
j'ai un soucis avec mon mapping hibernate et je ne sais pas du tout d'où ça vient. J'ai déjà testé plein plein de choses mais je dois être passé à côté ..
J'ai deux entités FILM et ACTEUR
J'ai une clé étrangère du FILM dans l'acteur qui me permet de faire le lien.
Au niveaux de mon mapping, dans mon film.hbm.xml, j'ai un set d'acteurs en cascade=all-delete-orphan.
Mon soucis est qu'actuellement lorsque j'update un Film en lui supprimant un acteur de sa liste d'acteurs .. ben tout est bien mis à jour SAUF les acteurs, pas d'erreur mais l'acteur est toujours en base avec l'id du film.
L'ajout d'un acteur dans la liste du film fonctionne, c'est uniquement la suppression qui plante silencieusement.
Au niveau des traces hibernate pas d'erreur ni d'instruction DELETE ..
Normal ?
Voici mes sources, et en avance, merci beaucoup
Acteur.hbm.xml
Code:
<hibernate-mapping package="fr.company.projet.daos" >
<class name="Acteur" table="T_ACTEUR" >
<id name="id" type="long" column="ID" >
<generator class="sequence">
<param name="sequence">S_ACTEUR</param>
</generator>
</id>
<property name="name" type="string" column="NAME"/>
<many-to-one name="film" class="Film" column="FILM_ID" not-null="true" />
</class>
</hibernate-mapping>
Film.hbm.xml
Code:
<hibernate-mapping package="fr.company.projet.daos" >
<class name="Film" table="T_FILM" >
<id name="id" type="long" column="ID" >
<generator class="sequence">
<param name="sequence">S_FILM</param>
</generator>
</id>
<property name="name" type="string" column="NAME"/>
<set name="acteurs" cascade="all-delete-orphan">
<key column="FILM_ID">
</key>
<one-to-many class="Acteur"/>
</set>
</class>
</hibernate-mapping>
Mon abstract DAO
Code:
public abstract class AbstractDaoImpl extends HibernateDaoSupport implements IAbstractDao {
public abstract String getDomainObjectName();
public abstract String getCamelCaseDomainObjectName();
public abstract Class getDomainObjectClass();
public AbstractDomainObject findById(Long id) throws DaoException, ObjectNotFoundException, CheckException {
return findById(id, true);
}
public AbstractDomainObject findById(Long id, boolean checkSoftDelete) throws DaoException, ObjectNotFoundException, CheckException {
if (id == null) {
throw new CheckException("l'id est obligatoire");
}
try {
AbstractDomainObject object = (AbstractDomainObject) getHibernateTemplate().load(getDomainObjectClass(), id);
if (object == null) {
throw new ObjectNotFoundException();
}
return object;
} catch (Exception e) {
throw new DaoException("ne peut pas recuperer l'objet. ", e);
}
}
/**
* generic count method used to retrieve the total object entities count
*
* @return int count
*/
public int count() throws DaoException, CheckException {
LOG.debug("entering "+getDomainObjectName()+"DAO.count()");
Criteria criteria = getSession().createCriteria(getDomainObjectClass());
criteria.add(Restrictions.gt("id", 0L));
criteria.setProjection(Projections.rowCount());
List result = criteria.list();
return ((Integer) result.get(0)).intValue();
}
/**
* generic count method used to retrieve the total object entities count with search criterias
*
* @param String[] criterias
* @param String[] values
* @return int count
*/
public int count(String[] criterias, String[] values) throws DaoException, CheckException {
LOG.debug("entering "+getDomainObjectName()+"DAO.count()");
Criteria criteria = getSession().createCriteria(getDomainObjectClass());
criteria.add(Restrictions.gt("id", 0L));
criteria.setProjection(Projections.rowCount());
if(criterias!=null){
for(int i=0;i<criterias.length;i++)
{
criteria.add(Restrictions.eq(criterias[i],values[i]));
}
}
List result = criteria.list();
return ((Integer) result.get(0)).intValue();
}
/**
* generic insert method used to insert a single object entity
*
* @param AbstractDomainObject object
* @return AbstractDomainObject
*/
public AbstractDomainObject insert(AbstractDomainObject object) throws DaoException, DuplicateKeyException, CheckException {
LOG.debug("entering "+getDomainObjectName()+"DAO.insert");
try {
// set creation values
object.setId((Long)getHibernateTemplate().save(object));
getHibernateTemplate().flush();
return object;
}
catch (GenericJDBCException ge) {
if ((ge.getCause() != null)
&& (ge.getCause() instanceof SQLException)) {
SQLException sqlException = (SQLException) ge.getCause();
if (sqlException.getErrorCode() == TpmConstantes.DATA_ALREADY_EXIST) {
throw new DuplicateKeyException();
} else {
throw new DaoException(ge);
}
} else {
throw new DaoException(ge);
}
} catch (DataAccessException e) {
throw new DaoException(e);
}catch (ConstraintViolationException cve) {
throw new DaoException(cve);
}
}
public AbstractDomainObject insertAndEvict(AbstractDomainObject value) throws Exception
{
AbstractDomainObject object = insert(value);
getHibernateTemplate().evict(object);
return object;
}
/**
* generic insert method used to delete a single object entity
*
* @param AbstractDomainObject object
* @return AbstractDomainObject
*/
public long delete(long id) throws DaoException,ObjectNotFoundException,CheckException {
//LOG.debug("entering "+getDomainObjectName()+"DAO.delete("+id)+")");
try {
AbstractDomainObject entity = (AbstractDomainObject)getSession().load(getDomainObjectClass(), id);
getSession().delete(entity);
//getHibernateTemplate().delete(object);
return entity.getId();
}
catch (DataAccessException e)
{
throw new DaoException(e);
}
}
/**
* generic update method used to delete a single object entity
*
* @param AbstractDomainObject object
* @return AbstractDomainObject
*/
public AbstractDomainObject update(AbstractDomainObject object) throws CheckException, DaoException, ObjectNotFoundException {
LOG.debug("entering "+getDomainObjectName()+"DAO.update("+object.getId()+")");
try {
getHibernateTemplate().saveOrUpdate(object);
getHibernateTemplate().flush();
return object;
}
catch (DataAccessException e)
{
throw new DaoException(e);
}
}
Pour ce qui est du reste ce n'est que du link bête et pas méchant.
En débugant lorsque j'arrive au "getHibernateTemplate().saveOrUpdate(object)" mon objet du domaine est bien formé sans l'élément supprimer dans sa collection d'acteurs. Mais rien à faire que je regarde la base après ou que je fais un find l'acteur supprimé refait son apparition.
Puis pour d'avantage de détails : la connexion se fait vers une BDD DB2, que j'utilise spring 2.5.6 et hibernate 3.2.7.ga
La moindre critique est la bienvenue, je ne sais plus quoi faire. Même une solution de rechange un peu plus crade me conviendra en attendant de trouver mieux.
Merci beaucoup