充血モデルの想定実現(2010/07/30更新)
2年前、貧血モデルと充血モデルの議論は熱烈だったが、具体的な実装では議論が多かった.肝心なのはJavaが動的言語ほど容易に実現できないためであり、分野モデルに関連するデータベースへのアクセス方法を動的に追加できれば、どのような状況になるのか.
最近バイトコードの操作に興味があり、領域モデルをコンパイルする際に、関連するバイトコードを動的に追加し、領域モデルを豊富にするとともにhibernateのサポートが必要となり、すべての@Entityの領域モデルを取得し、HibernateTemplate Fieldを追加し、aspectjを借りて領域モデルをインスタンス化する際にhibernateTemplateを注入したいと考えています.(Spring Rooはこのように実現されています...)(他のオブジェクトを注入する必要がある場合は、同じように)
各entityにpersistenceメソッドを追加すると、DAO層を省くことができます.ビジネス層はトランザクション、セキュリティなどのロジックを管理し、以下のコードのバイトコードを追加し、添付ファイルのコードを具体的に参照します.実際にはantコマンドを追加します.バイトコードを一括追加します.
テストの例は次のとおりです.
テストが终わってからですが、実际の开発はちょっと不便だと思います.entityコードを修正するには、バイトコードを再修正する必要があります.antを使うと便利ですが、entityにビジネス方法を追加しなければ、entityを修正する機会が少なく、受け入れられます.entityにビジネス方法を追加し、充血モデルを豊富にしたいなら、ちょっと面倒です.
しかし、lombokから、eclipseでjavaコードをコンパイルするときに、バイトコードを追加したり、lombokのコードを見たり、複雑なものがあったりする解決策を学びました.後で実現する時間がある...
最近バイトコードの操作に興味があり、領域モデルをコンパイルする際に、関連するバイトコードを動的に追加し、領域モデルを豊富にするとともにhibernateのサポートが必要となり、すべての@Entityの領域モデルを取得し、HibernateTemplate Fieldを追加し、aspectjを借りて領域モデルをインスタンス化する際にhibernateTemplateを注入したいと考えています.(Spring Rooはこのように実現されています...)(他のオブジェクトを注入する必要がある場合は、同じように)
// ASM :
@Transient
private HibernateTemplate hibernateTemplate;
public HibernateTemplate getHibernateTemplate() {
return hibernateTemplate;
}
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
各entityにpersistenceメソッドを追加すると、DAO層を省くことができます.ビジネス層はトランザクション、セキュリティなどのロジックを管理し、以下のコードのバイトコードを追加し、添付ファイルのコードを具体的に参照します.実際にはantコマンドを追加します.バイトコードを一括追加します.
public void create() throws DataAccessException {
hibernateTemplate.save(this);
}
public void createOrUpdate() throws DataAccessException {
hibernateTemplate.saveOrUpdate(this);
}
public void delete() throws DataAccessException {
hibernateTemplate.delete(this);
}
public Message find() throws DataAccessException {
return hibernateTemplate.get(this.getClass(), id);
}
public void update() throws DataAccessException {
hibernateTemplate.update(this);
}
public List<Message> findByProperty(String propertyName, Object value) throws DataAccessException {
Assert.hasText(propertyName);
Assert.notNull(value);
StringBuilder buf = new StringBuilder();
buf.append("FROM ").append(this.getClass().getSimpleName()).append(" WHERE ").append(propertyName).append(" = :condition");
List<Message> entities = this.getHibernateTemplate().findByNamedParam(buf.toString(), "condition", value);
return entities;
}
public List<Message> findAll() throws DataAccessException {
return (List<Message>) hibernateTemplate.loadAll(this.getClass());
}
テストの例は次のとおりです.
final HibernateTemplate hibernateTemplate = new HibernateTemplate();
HibernateTransactionManager transactionManager = new HibernateTransactionManager(HibernateSessionFactory.getSessionFactory());
hibernateTemplate.setSessionFactory(HibernateSessionFactory.getSessionFactory());
hibernateTemplate.afterPropertiesSet();
transactionManager.afterPropertiesSet();
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus arg0) {
Message message = new Message();
message.setHibernateTemplate(hibernateTemplate);
message.setText("Hello World");
message.create();
List<Message> list = message.findAll();
System.out.println(list.size() + "message(s) found");
}
});
HibernateSessionFactory.getSessionFactory().close();
テストが终わってからですが、実际の开発はちょっと不便だと思います.entityコードを修正するには、バイトコードを再修正する必要があります.antを使うと便利ですが、entityにビジネス方法を追加しなければ、entityを修正する機会が少なく、受け入れられます.entityにビジネス方法を追加し、充血モデルを豊富にしたいなら、ちょっと面倒です.
しかし、lombokから、eclipseでjavaコードをコンパイルするときに、バイトコードを追加したり、lombokのコードを見たり、複雑なものがあったりする解決策を学びました.後で実現する時間がある...