Bonjour,
J'ai un probleme avec la génération des clés dans une relation many-to-one. Je m'explique:
J'ai une objet Client auqu'elle j'ai associé une liste d'objet contactsClient
J'ai definie mon propre generateur pour les identifiants de ces deux classes.
L'identifiant des ContactClient s'obtient de facon incremental sur le numero de Client (voir code).
Mais lorsque j'enregistre un client avec deux contacts, il genere la même clé pour les deux contacts ce qui cause une violation de contrainte unique

- Fichiers HBM.XML
=============
Client :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
<hibernate-mapping package="com.srv.crm">
	<class
		name="Client"
		table="NOYP_CLIENT"
	>
		<meta attribute="sync-DAO">false</meta>
		<id
			name="id"
			type="string"
			column="ID"
		>
			<generator class="com.hibernate.IardGenerator"/>
		</id>
 
		<property
			name="code"
			column="CODE_CLIENT"
			type="string"
			not-null="true"
			length="25"
		/>
 
 		<set name="contacts" inverse="true" cascade="all, delete-orphan">
			<key column="ID_CLI"/>
			<one-to-many class="ContactClient"/>
		</set>
	</class>	
</hibernate-mapping>
ContactClient:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
<hibernate-mapping package="com.srv.crm">
	<class
		name="ContactClient"
		table="NOYP_CONTACT_CLIENT"
	>
		<meta attribute="sync-DAO">false</meta>
		<id
			name="id"
			type="string"
			column="CODE_CONTACTCLI"
		>
			<generator class="com.srv.hibernate.IardGenerator"/>
		</id>		
		<property
			name="nomContact"
			column="NOM_CONTACTCLI"
			type="string"
			not-null="true"
			length="64"
		/>				
		<many-to-one
			name="client"
				class="Client"
				column="ID_CLI"
			not-null="true"
		>
		</many-to-one>
 
	</class>	
</hibernate-mapping>
-Codes sources IDGenerator
=====================

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
 
 package com.srv.hibernate;
 
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java. Properties;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.exception.JDBCExceptionHelper;
import org.hibernate.id.Configurable;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.jdbc.Batcher;
import org.hibernate.mapping.Table;
import org.hibernate.type.Type;
import org.hibernate. StringHelper;
 
public class IardGenerator implements IdentifierGenerator, Configurable {
	private String next;
 
	private String sql;// = "select max(ID) from NOYP_BRANCHE";
 
	private String prefixe = null;
 
	private int tail = 0;
 
	private String col;
 
	public synchronized Serializable generate(SessionImplementor session,
			Object object) throws HibernateException {
		String[] tmp =  getPrefixe(object).split("#");
		prefixe = tmp[0];
		if (tmp.length > 1)
			tail = Integer.parseInt(tmp[1]);
		if (sql != null) {
			getNext(session);
		}
		System.err.println("GENERATION de l'object " + object.toString()
				+ " cle=" + next);
		return next;
	}
 
	public void configure(Type type, Properties params, Dialect dialect)
			throws MappingException {
		// obtention du nom de la table
		String tableList = params.getProperty("tables");
		if (tableList == null)
			tableList = params
					.getProperty(PersistentIdentifierGenerator.TABLES);
		// liste de toutes les tables
		String[] tables = StringHelper.split(", ", tableList);
		// recherche de la colonne
		String column = params.getProperty("column");
		if (column == null)
			column = params.getProperty(PersistentIdentifierGenerator.PK);
		// recherche du schema
		String schema = params
				.getProperty(PersistentIdentifierGenerator.SCHEMA);
		// recherche du catalogue
		String catalog = params
				.getProperty(PersistentIdentifierGenerator.CATALOG);
 
		StringBuffer buf = new StringBuffer();
		for (int i = 0; i < tables.length; i++) {
			if (tables.length > 1) {
				buf.append("select ").append(column).append(" from ");
			}
			buf.append(Table.qualify(catalog, schema, tables[i]));
			if (i < tables.length - 1)
				buf.append(" union ");
		}
		if (tables.length > 1) {
			buf.insert(0, "( ").append(" ) ids_");
			column = "ids_." + column;
		}
 
		sql = "select max(" + column + ") from " + buf.toString();
		col = column;
		System.err.println("REQUETTE= " + sql);
	}
 
	private void getNext(SessionImplementor session) {
		try {
			StringBuffer buf = new StringBuffer();
			buf.append(sql).append(" where ").append(col).append(" like '").append(prefixe).append("%'");
			System.err.println("REQUETTE A EXE = " + buf.toString());
			Batcher bc = session.getBatcher();
			PreparedStatement st = bc.prepareSelectStatement(
					buf.toString());
			try {
				ResultSet rs = bc.getResultSet(st);//st.executeQuery();
				try {
					if (rs.next()) {
						// next = rs.getLong(1) + 1;
						try {
							String ret = rs.getString(1);							
							long val = Long.parseLong(ret.substring(ret.indexOf(prefixe)+prefixe.length()));
							val++;
							next = prefixe +  completer(tail, val);
						} catch (Exception e) {
							next = prefixe +  completer(tail, 1);
						}
						if (rs.wasNull()) {
							next = prefixe + completer(tail, 1);
						}
					} else {
						next = prefixe + completer(tail, 1);
					}
					// sql = null;
					// log.debug("first free id: " + next);
				} finally {
					rs.close();
				}
			} finally {
				session.getBatcher().closeStatement(st);
			}
 
		} catch (SQLException sqle) {
			throw JDBCExceptionHelper.convert(session.getFactory()
					.getSQLExceptionConverter(), sqle,
					"could not fetch initial value for increment generator",
					sql);
		}
	}
 
	public static String completer(int tail,long val) {
		System.err.println("ON COMPLETTE= "+val);
		StringBuffer buf = new StringBuffer();
		//buf.append(patern);
		buf.append("0000000000000000000").append(Long.toString(val));
		buf.substring(buf.length() - tail, buf.length());
		return buf.substring(buf.length() - tail, buf.length());
	}
	public static String getPrefixe(Object obj){		
		if(obj instanceof Client){
			return "CLI#10";
		}
		if(obj instanceof ContactClient){
			StringBuffer buf = new StringBuffer();
			buf.append(((ContactClient)obj).getClient()
					.getId()).append("#2");
			return buf.toString();
		}
		return "0#0";
	}
 
}
MErci de vos aides