2010-06-21 5 views
4

J'ai une application qui utilise déjà le framework Spring et Spring JDBC avec une couche DAO en utilisant les classes SimpleJdbcTemplate et RowMapper. Cela semble fonctionner très bien avec de petites structures de classes lues à partir de la base de données. Cependant, nous avons besoin de charger des objets qui contiennent des collections d'autres objets, qui contiennent encore des collections d'autres objets. La solution «évidente» à ce problème est de créer une classe nommée RowMapper ou nos objets, et de passer des références aux objets DAO appropriés dans le constructeur. Par exemple:Spring Framework JDBC avec DAO agrgegation/composition

public class ProjectRowMapper implements ParameterizedRowMapper { 

    public ProjectRowMapper(AccountDAO accountDAO,) { 
     this.accountDAO = accountDAO; 
    } 

    public Project mapRow(ResultSet rs, int rowNum) throws SQLException { 
     Project project= new Project(); 
     project.setProjecttId(rs.getString("project_id")); 
     project.setStartDate(rs.getDate("start_date")); 
     // project.setEtcetera(...); 

     // this is where the problems start 
     project.setAccounts(accountDAO.getAccountsOnProject(project.getProjectId())); 
    } 
} 

Le problème est que même si le ProjectDAO et la part de DAO compte de la même instance de DataSource (dans notre cas est un pool de connexion), tout accès de base de données sont effectués par une autre connexion.

Si la hiérarchie des objets est même trois niveaux de profondeur, en utilisant le cadre de datasource.getConnection() cette mise en œuvre entraîne (a) de nombreux appels et (2) encore pire, puisque nous limitons le nombre de connexions autorisé dans notre pool de connexions, conditions de concurrence potentielles pendant que plusieurs threads tentent de charger un projet à partir de la base de données.

Y at-il une meilleure façon au printemps (sans autre outil ORM à part entière) pour obtenir la charge de ces hiérarchies d'objets?

Merci, Paul

+1

Un outil ORM complet est exactement ce dont vous avez besoin ici. Ces problèmes sont difficiles, ne les réinventez pas. – skaffman

+1

Y a-t-il une transaction autour de votre code? Nous utilisons le même modèle dao imbriqué pour charger des objets complexes, mais Spring JDBC n'utilise qu'une seule connexion – Serxipc

Répondre

2

Je suppose que vous avez des raisons de ne pas utiliser un ORM, qui est l'outil idéal pour ce genre de problème.

Le problème avec plusieurs connexions est l'appel récursif à un autre DAO. Pour éviter de consommer des connexions supplémentaires, les objets Compte doivent être récupérés plus tard, une fois l'instance de projet récupérée. Lors de l'extraction du projet, les accountID sont également récupérés, mais pas "instanciés" aux instances de compte. Ils restent sous la forme d'une liste d'ID, qui sont ensuite renseignés après que le DAO du projet a effectué son travail. Par exemple, vous pouvez créer un type liste personnalisé qui prend une liste d'ID et une implémentation DAO. La liste est remplie uniquement avec les ID dans ProjectRowMapper et affectée à la propriété accounts du projet. Les ID sont privés à la liste - ils ne sont pas le «contenu» de la liste, mais un moyen de produire le contenu réel plus tard. Une fois que le DAO du projet a récupéré les projets à partir de RowMapper, il peut ensuite demander à la liste de récupérer les comptes pour les ID enregistrés dans la liste. Les comptes sont récupérés en tant qu'opération non imbriquée et l'intégralité du processus n'utilise qu'une connexion à la fois. Pourtant, l'extraction est effectuée dans le cadre de la méthode DAO, donc l'extraction est effectuée avec empressement - donc il n'y a pas de problèmes de chargement paresseux à traiter.

+0

C'est ce que j'ai fait, et cela fonctionne merveilleusement pour le moment. –

Questions connexes