2010-05-12 6 views
4

Nous avons 2 applications web java en lecture/écriture et 3 applications de lecture/écriture java autonomes (on charge des questions par email, on traite un flux xml, on envoie des emails aux abonnés) hiberner et partager une base de code commune.Intégrité de base de données Hibernate avec plusieurs applications Java

Le problème que nous avons récemment rencontré est que les questions chargées par e-mail remplacent parfois les questions créées dans l'une des applications Web. Notez que ce sont des questions distinctes qui devraient avoir des identifiants séparés. Nous pensions initialement que c'était un problème de mise en cache. Nous avons essayé de désactiver le cache de second niveau, mais cela ne fait pas de différence.

<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property> 
<property name="hibernate.current_session_context_class">thread</property> 
<property name="hibernate.cache.use_second_level_cache">false</property> 

Question:

@Id 
@GeneratedValue(strategy = IDENTITY) 
@Column(name = "id", unique = true, nullable = false) 
@DocumentId 
public Integer getId() { 
    return this.id; 
} 

Nous utilisons MySQL btw.

CREATE TABLE `question` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    ... 
    PRIMARY KEY (`id`), 
    ... 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

Nous ne sommes pas explicitement ouvrirons et la fermeture de sessions, mais laissez-les gérer via Util.getSessionFactory().getCurrentSession() mise en veille prolongée. Nous préférons ne pas configurer de cache de second niveau en cluster à ce stade, car cela crée une autre couche de complexité et nous sommes plus que satisfaits du niveau de performance que nous obtenons de l'application dans son ensemble.

La mise en œuvre d'un modèle de session ouverte en vue dans les applications Web et la gestion manuelle des sessions dans les applications autonomes semblent-elles résoudre ce problème?

Ou d'autres suggestions/idées s'il vous plaît?

+0

Comment les questions identifiées (aussi quelle est la clé primaire) sont les mises à jour du courrier et du Web à la même question? – Mark

+0

Il semble que la clé primaire soit générée par les applications au lieu d'utiliser une séquence gérée par la base de données. – khmarbaise

+0

Salut, juste mis à jour ma question avec plus d'informations pour vous. Je pensais que la stratégie IDENTITY a provoqué la génération de l'identifiant par MySQL? – Austen

Répondre

0

Il s'avère que ce problème n'était pas du tout lié à Hibernate.

L'une des tables de base de données sur le serveur de transfert a été remplie avec les anciennes données qui auraient dû être nettoyées. Cela a d'abord donné l'apparence de l'identification est écrasée, mais une enquête plus poussée prouve le contraire! Une fois que nous avons supprimé les données douteuses, tout allait bien.

3

Puisque toutes les questions ont des identifiants, alors je suppose que toutes les questions sont extraites de votre base de données MySQL.

En supposant que vous n'avez pas besoin de stocker les questions en tant qu'objets transparents en mémoire, mais que vous sélectionnez toutes les questions pour chaque fois que vous les présentez, j'ai une suggestion simple.

Remplacez le générateur d'ID par une séquence dans la base de données. (Finalement, l'ID en tant que numéro automatique dans MySQL). Ensuite, la base de données au lieu des applications garantit que chaque question obtient un identifiant unique.

Cette solution est assez simple et réduit votre complexité. Et cela ne fonctionne que si vous persistez toutes les questions entrantes des différentes sources dans votre base de données, puis sélectionnez-les ici.

Si cette solution vous pose des problèmes de performances, vous devez en savoir plus sur le fonctionnement de votre générateur d'ID Hibernate. Hibernate fournit plusieurs générateurs différents pour différents scénarios.

Espérons que cette aide!

+0

J'ai ajouté notre schéma pour les questions. alors suggérez-vous de supprimer l'annotation @GeneratedValue (strategy = IDENTITY)? – Austen

+0

Oui, oui. Si plusieurs applications insèrent des valeurs dans la même table, un déclencheur d'insertion sur la table est la solution la plus à l'épreuve des balles. Ce déclencheur doit définir les identifiants d'une séquence. – Espen

+0

Si je supprime l'annotation @GeneratedValue, j'obtiens: org.hibernate.id.IdentifierGenerationException: les identifiants de cette classe doivent être attribués manuellement avant d'appeler save(): Suggérez-vous que je trouve manuellement l'identifiant directement depuis la base de données, puis affecter manuellement à de nouvelles questions? – Austen

Questions connexes