2009年7月24日 (金)

JBoss5.xでのHibernate deploy設定について

一つ前の記事で JBoss5.x系でHibernateのdeployの扱い・設定が変わったことにふれました。
参考:http://www.jboss.org/community/wiki/JBossHibernate3

で肝心の設定どうやるの??
というときにドキュメントが見つからない!!
JBossHibernate3 か JBossAS5のドキュメントのどこかにはありそうな気もします。
が見つからないものはしょうがないので感でやってみました。

こんな感じ?

<hibernate-configuration xmlns="urn:jboss:hibernate-deployer:1.0">
    <session-factory
        name="java:/hibernate/adminuser"
        bean="jboss.test.har:service=Hibernate">
        <property name="datasourceName">java:/jdbc/adminuser</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

       <!--↓ココがかんでたしたとこ-->
   <property name="show_sql">false</property>

      <depends>jboss:service=Naming</depends>
      <depends>jboss:service=TransactionManager</depends>
    </session-factory>
</hibernate-configuration>

デプロイ結果

java.lang.RuntimeException: Error configuring property: show_sql for jboss.test.har:service=Hibernate
    at org.jboss.kernel.plugins.dependency.ConfigureAction.dispatchSetProperty(ConfigureAction.java:112)
    at org.jboss.kernel.plugins.dependency.ConfigureAction.setAttributes(ConfigureAction.java:85)
    at org.jboss.kernel.plugins.dependency.ConfigureAction.installActionInternal(ConfigureAction.java:44)
    at org.jboss.kernel.plugins.dependency.InstallsAwareAction.installAction(InstallsAwareAction.java:54)
    at org.jboss.kernel.plugins.dependency.InstallsAwareAction.installAction(InstallsAwareAction.java:42)
    at org.jboss.dependency.plugins.action.SimpleControllerContextAction.simpleInstallAction(SimpleControllerContextAction.java:62)
    at org.jboss.dependency.plugins.action.AccessControllerContextAction.install(AccessControllerContextAction.java:71)
    at org.jboss.dependency.plugins.AbstractControllerContextActions.install(AbstractControllerContextActions.java:51)
    at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348)
    at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1631)
    at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:934)
    at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082)
    at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:984)
    at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:774)
    at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:540)
    at org.jboss.deployers.vfs.deployer.kernel.BeanMetaDataDeployer.deploy(BeanMetaDataDeployer.java:121)
    at org.jboss.deployers.vfs.deployer.kernel.BeanMetaDataDeployer.deploy(BeanMetaDataDeployer.java:51)
    at org.jboss.deployers.spi.deployer.helpers.AbstractSimpleRealDeployer.internalDeploy(AbstractSimpleRealDeployer.java:62)
    at org.jboss.deployers.spi.deployer.helpers.AbstractRealDeployer.deploy(AbstractRealDeployer.java:50)
    at org.jboss.deployers.plugins.deployers.DeployerWrapper.deploy(DeployerWrapper.java:171)
    at org.jboss.deployers.plugins.deployers.DeployersImpl.doDeploy(DeployersImpl.java:1439)
    at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1157)
    at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1178)
    at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1210)
    at org.jboss.deployers.plugins.deployers.DeployersImpl.install(DeployersImpl.java:1098)
    at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348)
    at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1631)
    at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:934)
    at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082)
    at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:984)
    at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:822)
    at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:553)
    at org.jboss.deployers.plugins.deployers.DeployersImpl.process(DeployersImpl.java:781)
    at org.jboss.deployers.plugins.main.MainDeployerImpl.process(MainDeployerImpl.java:702)
    at org.jboss.system.server.profileservice.repository.MainDeployerAdapter.process(MainDeployerAdapter.java:117)
    at org.jboss.system.server.profileservice.hotdeploy.HDScanner.scan(HDScanner.java:362)
    at org.jboss.system.server.profileservice.hotdeploy.HDScanner.run(HDScanner.java:255)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(Unknown Source)
    at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: No such property hibernate for bean org.jboss.hibernate.jmx.Hibernate available
[statisticsServiceName, beanName, defaultSchema, defaultCatalog, sessionFactoryName, querySubstitutions, secondLevelCacheEnabled, password, version, statGenerationEnabled, maxFetchDepth, username, useStructuredCacheEntriesEnabled, datasourceName, dirty, streamsForBinaryEnabled, getGeneratedKeysEnabled, hbm2ddlAuto, minimalPutsEnabled, instance, jdbcBatchSize, jdbcScrollableResultSetEnabled, cacheRegionFactoryClass, dialect, scanForMappingsEnabled, runningSince, cacheRegionPrefix, class, cacheProviderClass, sessionFactoryRunning, batchVersionedDataEnabled, harUrl, queryCacheEnabled, sessionFactoryInterceptor, deployedCacheManagerJndiName, showSqlEnabled, reflectionOptimizationEnabled, jdbcFetchSize, listenerInjector, sqlCommentsEnabled, deployedCacheJndiName, controller]
    at org.jboss.beans.info.plugins.AbstractBeanInfo.getProperty(AbstractBeanInfo.java:147)
    at org.jboss.beans.info.plugins.BeanInfoUtil.getNestedPropertyInfo(BeanInfoUtil.java:111)
    at org.jboss.beans.info.plugins.BeanInfoUtil.getPropertyInfo(BeanInfoUtil.java:197)
    at org.jboss.kernel.plugins.dependency.PropertyDispatchWrapper.execute(PropertyDispatchWrapper.java:77)
    at org.jboss.kernel.plugins.dependency.ExecutionWrapper.execute(ExecutionWrapper.java:47)
    at org.jboss.kernel.plugins.dependency.KernelControllerContextAction.dispatchExecutionWrapper(KernelControllerContextAction.java:109)
    at org.jboss.kernel.plugins.dependency.ConfigureAction.dispatchSetProperty(ConfigureAction.java:107)
    ... 45 more

まあでもヒントをエラーメッセージ中から発見しました。
オレンジの部分見てください!!
この中に該当しないと指摘されています。
逆にこの中に該当すればよいわけです。

抜き出してみました

statisticsServiceName,
beanName,
defaultSchema,
defaultCatalog,
sessionFactoryName,
querySubstitutions,
secondLevelCacheEnabled,
password,
version,
statGenerationEnabled,
maxFetchDepth,
username,
useStructuredCacheEntriesEnabled,
datasourceName,
dirty,
streamsForBinaryEnabled,
getGeneratedKeysEnabled,
hbm2ddlAuto,
minimalPutsEnabled,
instance,
jdbcBatchSize,
jdbcScrollableResultSetEnabled,
cacheRegionFactoryClass,
dialect,
scanForMappingsEnabled,
runningSince,
cacheRegionPrefix,
class,
cacheProviderClass,
sessionFactoryRunning,
batchVersionedDataEnabled,
harUrl,
queryCacheEnabled,
sessionFactoryInterceptor,
deployedCacheManagerJndiName,
showSqlEnabled,
reflectionOptimizationEnabled,
jdbcFetchSize,
listenerInjector,
sqlCommentsEnabled,
deployedCacheJndiName,
controller

あとはHibernateの設定項目と照らし合わせて設定すればよい感じですね
参考:http://www.redhat.com/docs/manuals/jboss/jboss-eap-4.2/ja_JP/html/Hibernate_Reference_Guide/Configuration-Optional_configuration_properties.html

<hibernate-configuration xmlns="urn:jboss:hibernate-deployer:1.0">

    <!-- a SessionFactory instance listed as /jndi/name -->
    <session-factory
        name="java:/hibernate/adminuser"
        bean="jboss.test.har:service=Hibernate">

        <!-- properties -->
        <property name="datasourceName">java:/jdbc/adminuser</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="showSqlEnabled">false</property>
        <property name="queryCacheEnabled">true</property>
        <property name="jdbcBatchSize">50</property>
       
      <depends>jboss:service=Naming</depends>
      <depends>jboss:service=TransactionManager</depends>

    </session-factory>

</hibernate-configuration>

こんな感じ?
…ココまで書いて気がついた(--;
JBoss4.x系の設定項目の頭を小文字にしただけだ!!
まぁよしとしましょう

2009-07-24 13:27:50,931 INFO  [org.jboss.web.tomcat.service.deployers.TomcatDeployment] (HDScanner) undeploy, ctxPath=/admin
2009-07-24 13:27:51,134 INFO  [org.jboss.hibernate.deployers.HibernateDeployer] (HDScanner) Created Hibernate bean: AbstractBeanMetaData@f185b0{name=jboss.test.har:service=Hibernate bean=org.jboss.hibernate.jmx.Hibernate properties=[dialect, jdbcBatchSize, datasourceName, showSqlEnabled, queryCacheEnabled, sessionFactoryName] constructor=AbstractConstructorMetaData@80188f{parameters=[org.jboss.virtual.VirtualFile]} autowireCandidate=true depends=[jboss:service=Naming, jboss:service=TransactionManager]}
2009-07-24 13:27:51,165 INFO  [org.hibernate.cfg.HbmBinder] (HDScanner) Mapping class: neoplus.admin.data.RoleData -> role_data
2009-07-24 13:27:51,165 INFO  [org.hibernate.cfg.HbmBinder] (HDScanner) Mapping class: neoplus.admin.data.UserData -> user_data
2009-07-24 13:27:51,165 INFO  [org.hibernate.cfg.HbmBinder] (HDScanner) Mapping class: neoplus.admin.data.RoleMap -> role_map
2009-07-24 13:27:51,165 INFO  [org.hibernate.cfg.HbmBinder] (HDScanner) Mapping collection: neoplus.admin.data.UserData.roleMaps -> role_map
2009-07-24 13:27:51,165 INFO  [org.hibernate.util.NamingHelper] (HDScanner) JNDI InitialContext properties:{}
2009-07-24 13:27:51,180 INFO  [org.hibernate.connection.DatasourceConnectionProvider] (HDScanner) Using datasource: java:/jdbc/adminuser
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) RDBMS: MySQL, version: 5.1.34-community
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) JDBC driver: MySQL-AB JDBC Driver, version: mysql-connector-java-5.0.0-beta ( $Date: 2005-11-17 16:14:47 +0100 (Thu, 17 Nov 2005) $, $Revision$ )
2009-07-24 13:27:51,180 INFO  [org.hibernate.dialect.Dialect] (HDScanner) Using dialect: org.hibernate.dialect.MySQLDialect
2009-07-24 13:27:51,180 INFO  [org.hibernate.transaction.TransactionFactoryFactory] (HDScanner) Transaction strategy: org.hibernate.transaction.JTATransactionFactory
2009-07-24 13:27:51,180 INFO  [org.hibernate.util.NamingHelper] (HDScanner) JNDI InitialContext properties:{}
2009-07-24 13:27:51,180 INFO  [org.hibernate.transaction.TransactionManagerLookupFactory] (HDScanner) instantiating TransactionManagerLookup: org.hibernate.transaction.JBossTransactionManagerLookup
2009-07-24 13:27:51,180 INFO  [org.hibernate.transaction.TransactionManagerLookupFactory] (HDScanner) instantiated TransactionManagerLookup
2009-07-24 13:27:51,180 INFO  [org.hibernate.transaction.TransactionManagerLookupFactory] (HDScanner) instantiating TransactionManagerLookup: org.hibernate.transaction.JBossTransactionManagerLookup
2009-07-24 13:27:51,180 INFO  [org.hibernate.transaction.TransactionManagerLookupFactory] (HDScanner) instantiated TransactionManagerLookup
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Automatic flush during beforeCompletion(): enabled
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Automatic session close at end of transaction: enabled
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) JDBC batch size: 50
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) JDBC batch updates for versioned data: disabled
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Scrollable result sets: enabled
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) JDBC3 getGeneratedKeys(): enabled
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Connection release mode: after_statement
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Maximum outer join fetch depth: 2
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Default batch fetch size: 1
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Generate SQL with comments: disabled
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Order SQL updates by primary key: disabled
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Order SQL inserts for batching: disabled
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
2009-07-24 13:27:51,180 INFO  [org.hibernate.hql.ast.ASTQueryTranslatorFactory] (HDScanner) Using ASTQueryTranslatorFactory
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Query language substitutions: {}
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) JPA-QL strict compliance: disabled
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Second-level cache: enabled
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Query cache: enabled
2009-07-24 13:27:51,180 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Cache region factory : org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge
2009-07-24 13:27:51,180 INFO  [org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge] (HDScanner) Cache provider: org.hibernate.cache.HashtableCacheProvider
2009-07-24 13:27:51,196 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Optimize cache for minimal puts: disabled
2009-07-24 13:27:51,196 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Structured second-level cache entries: disabled
2009-07-24 13:27:51,196 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Query cache factory: org.hibernate.cache.StandardQueryCacheFactory
2009-07-24 13:27:51,196 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Statistics: disabled
2009-07-24 13:27:51,196 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Deleted entity synthetic identifier rollback: disabled
2009-07-24 13:27:51,196 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Default entity-mode: pojo
2009-07-24 13:27:51,196 INFO  [org.hibernate.cfg.SettingsFactory] (HDScanner) Named query checking : enabled
2009-07-24 13:27:51,196 INFO  [org.hibernate.impl.SessionFactoryImpl] (HDScanner) building session factory
2009-07-24 13:27:51,227 INFO  [org.hibernate.impl.SessionFactoryObjectFactory] (HDScanner) Not binding factory to JNDI, no JNDI name configured
2009-07-24 13:27:51,227 INFO  [org.hibernate.util.NamingHelper] (HDScanner) JNDI InitialContext properties:{}
2009-07-24 13:27:51,227 INFO  [org.hibernate.cache.UpdateTimestampsCache] (HDScanner) starting update timestamps cache at region: org.hibernate.cache.UpdateTimestampsCache
2009-07-24 13:27:51,227 INFO  [org.hibernate.cache.StandardQueryCache] (HDScanner) starting query cache at region: org.hibernate.cache.StandardQueryCache
2009-07-24 13:27:51,227 INFO  [org.jboss.hibernate.jmx.Hibernate] (HDScanner) SessionFactory successfully built and bound into JNDI [java:/hibernate/adminuser]
2009-07-24 13:27:51,305 INFO  [org.jboss.web.tomcat.service.deployers.TomcatDeployment] (HDScanner) deploy, ctxPath=/admin
2009-07-24 13:27:51,368 WARN  [org.jboss.web.tomcat.service.deployers.TomcatDeployment] (HDScanner) Failed to setup clustering, clustering disabled. NoClassDefFoundError: org/jboss/cache/pojo/jmx/PojoCacheJmxWrapperMBean

ぶじデプロイできました

| | コメント (0) | トラックバック (0)

2009年7月22日 (水)

JBoss5でhar設定が大幅に変わった件

以前この記事は「JBossでharがサポートされていないもよう」としていたのですが
完全に誤報だったので修正。

JBoss 5.x でharの扱いが変わりました。
以前までHibernate Arcaive (HAR)というあつかいでしたが
JBoss5.xからは Hibernate deployとなり
Hibernateの特殊なアーカイブではなくHibernateをJMX(JBossXB?)で
リソースとしてdeployできるというような扱いになったようです。
deployerもHARDeployerからhibernate deployer jboss beansとなっています。

設定ファイルも
[hibernate-service.xml]→[xxxxxxxxx-hibernate.xml](xxは任意)とかわり
フォーマットも変わっています。

詳しくはコチラをご覧ください
http://www.jboss.org/community/wiki/JBossHibernate3

JBoss5でharがさぽーとされていないもよう

JBoss5にharがサポートされていない様子です。
ドキュメントからharの記述が消えてしまいました。
…EJB3を使えて言うことでしょうか?

自分はどうも

呼び出しクラス → ステートレスBean  → エンティティBean

の構造になじめません。
少人数の開発では分業メリットはでないしめんどくさいんですよね。
どうしようか??
フレームワークの利用を検討中です。

| | コメント (0) | トラックバック (0)

2008年8月 6日 (水)

HQLでinsert(準備稿)

HQLでinsertが使えるって??
めちゃくちゃ便利じゃないかこれ…ちょっと開発が立て込んでいるのでとりあえずメモ
後でちゃんと記事にします。

http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=78&t=002695

OK. Well the reason I ask why you want to do it in HQL, is because HQL only supports insert from another table, so:

code:



Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String insertStatement = "insert into Object (id, name) select oo.id, oo.name from OtherObject oo";
s.createQuery( insertStatement ).executeUpdate();
tx.commit();
session.close();


would be how you do it.

Looking at your code above however there is no other table to select from.

| | コメント (0) | トラックバック (0)

2008年2月22日 (金)

HQLでINを使用して配列で検索

HQLでINを使用して配列で検索する方法にクセがあったのでまとめです。
…分かりづらい表題で申し訳ない。

※例では架空のHTTPのアクセスログからレコードを検索しています。

◆基本パターン
db_session.createQuery("from AccessLog log where log.url in ('/index.html','/infomation.html')");

ここでURLを変更できるようにしたいと思う…。

String[] url_list = {'/index.html','/infomation.html','/link.html'};
db_session.createQuery("from AccessLog log where log.url in (:urls)").setParameterList("urls",url_list);

ポイント:
① setParameterList メゾットを利用してパラメータを設定する
② :urls の部分を必ず()で囲む

そんなにひねくれてないかもしれないけど、自分は②が分からずに相当苦労した。
知っていればああそうですむ話(^^;

| | コメント (0) | トラックバック (0)

2007年8月20日 (月)

Hibernateアーカイブ(sar)とHot deployでうまくいかなかったこと

雑記メモです以下のようなことがありました。

JBossのHibernateアーカイブ(har)を使用するとデータベースコネクションが
JBoss管理のTransactionに入ります。
同コネクションを使用してINSERTやUTDATEのSQLを直に実行しようとすると
Transactionがでしゃばってきてエラーを返します。

そこでHot deployを利用してHibernateアーカイブを削除してみました。
ところがデータベースコネクションはJBoss管理下のTransactionから抜けることがなく
SQLの更新命令はエラーのままです。

JBossを再起動すると(当然ですが)データベースコネクションはTransactionから抜けて
SQLは受け入れられるようになりました。

総括ではないですが、あるデータベースに対してJDBC(SQL)直制御+Hibernate制御
を行う場合JBossのHibernateアーカイブは不適当なようです。
(SQLでリードのみを行う場合干渉は無い、Write系で問題発生)
ちなみにアーカイブにせずにwarアーカイブ内にHibernateの制御ファイルを
埋め込むパターンではこのような干渉行為は起きませんでした。

*注 この記事の内容は各バージョンでの動作の違いなど細かい検証をしていません。
         ご自分の環境で試すことを推奨します。

| | コメント (0) | トラックバック (0)

2007年8月13日 (月)

hibernate HQL count(*)の値でorderする

ひょっとしたらHibernateネタではなくてSQLネタかもしれない。
*注:例は仮想のテーブルhttpのアクセスログを想定しています。

select ip_address,count(*) as access_count from accress_log group by ip_address order by access_count;

上記のようなSQLを想定して

select log.ipAddress,count(log) as accessCount from AccessLog log group by log.ipAddress order by accessCount;

このようなHQLを書いてもHibernateの処理が通らなかった
どうやら別名でのorder by 句が通らないらしい。
自分はこのパターンしか知らなかったがSQLの辞書にて以下の構文を発見。

select ip_address,count(*) as access_count from accress_log group by ip_address order by 2;

要素を列挙する時の出現順番でorder byを指定することができる。
早速HQLに直してみたところ以下のような文で見事パスした。

select log.ipAddress,count(log) as accessCount from AccessLog log group by log.ipAddress order by 2;

赤字HQL 
青字SQL

| | コメント (0) | トラックバック (0)

2007年7月12日 (木)

HQL(Hibernate)でcount(*)の扱い方

HibernateのHQLでcountを使用した場合オブジェクトへのバインドが
LongになったりIntegerになったりします。
Hibernateのバージョンなどで変ってくるので、それを踏まえてしっかりコーディングしないと
移植などの時に困ったことになります。(自分は困った人です(=_=;))

◆まず悪い例
Integer value = (Integer)db_session.createQuery("select count(log.id) from Log  log").uniqueResult();

◆いい例①
Integer value = new Integer(((Number)db_session.createQuery("select count(log.id) from Log  log").uniqueResult()).intValue());

◆いい例②
Integer value = (Integer)db_session.createSQLQuery("select count(*) as ct from  log").addScalar("ct",new org.hibernate.type.IntegerType()).uniqueResult();

型が予想できないこともあるのでやはり扱い方をあらかじめ通知してあげるのが最適ですね。

| | コメント (0) | トラックバック (0)

2007年1月30日 (火)

Hibernate コレクション の追加/削除処理のコツ

Hibernateでコレクションに登録されているエンティティを
コレクションを保持するエンティティの更新と同時に削除したり追加しようとすると
うまくいかないことがあるので扱い方のメモ。

◆エンティティを更新とコレクションの一部を削除を同時に処理

boss.setName("baramos");
Set zako_set = boss.getZakos();
Object[] zako_array = zako_set.toArray();
for(int i=0;i<zako_array.length;i++){
    Zako zako = (Zako)zako_array[i];
    if(zako.getId.intValue() == 1000){
        db_session.delete(zako);
        zako_set.remove(zako);

    }
}
db_session.update(boss);

ポイントはsession に削除を通知して同時にコレクションからもはずすところ。
怠ると削除されない(bossを更新しなければ削除される)

◆エンティティを更新とコレクションに要素追加を同時に処理

boss.setName("baramos");
Set zako_set = boss.getZakos();
Zako zako = new Zako();
zako.setId(1000);
zako.setName("suraimu A");
zako.setBoss(boss);
zako_set.add(zako);
db_session.update(boss);

コレクションに追加するのがポイント

思うに意図したとおりに動かない場合の原因のほとんどはHibernateが
処理を要求された時ではなくトランザクションの処理時(commit)にそれまでに
要求があった処理を効率的に処理しようとするのが原因だと思う。

セッションに削除が指示されても保持エンティティのコレクションに
存在していると削除すべきかどうかが判断できないということ(?)
コレクションから削除しただけでは削除されないのは他のエンティティの
コレクションに追加されたりコレクションから切り離されて
レコードが存在する可能性があるから(?)

| | コメント (0) | トラックバック (0)

2007年1月18日 (木)

JBoss 4.0.4GAでHibernateのバージョンが上がった件

JBossをアプリケーションサーバーとしていつもどおりセットアップしていたら
Hibernateが何故か動作しない

エラーメッセージは

Exception happened while executing page: tried to access method net.sf.ehcache.CacheManager.

()V from class org.hibernate.cache.EhCacheProvider  

なかんじ

検索した結果

http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3962394

JBossに同胞されているHibernateのバージョンが上がったようす(3.2)です。
それに伴い必要なjarが ehcache-1.1.jar ⇒ ehcache-1.2.3.jar となりました。
Hibernate をDLするともれなくついてきます。

http://ehcache.sourceforge.net/

http://www.hibernate.org/6.html

| | コメント (0) | トラックバック (0)

2006年12月28日 (木)

JBossのHibernateContextが便利そうだ

◆元ネタ◆

http://docs.jboss.org/jbossas/jboss4guide/r2/html/ch13.html#ch13.caveat-har.fig

JBoss provides the                 org.jboss.hibernate.session.HibernateContext             class as the integration piece that does this. The                 getSession method returns a Hibernate session             that is linked to the current JTA transaction. Naturally this             requires that a JTA transaction exist prior to the call. The             following code illustrates the use of getSession.

Session hsession = HibernateContext.getSession("java:/hibernate/CaveatEmptorSessionFactory");

When you get the Hibernate session in this manner, you don't need             close the Hibernate session or manage a hibernate transaction. You             can be sure that all access to the Hibernate session from the             current transaction will see the same state, and you can know that             your Hibernate access will be committed to the database or rolled             back along with the larger JTA transaction.

↑は登録ユーザーのみ閲覧できるスペースなのでひょっとすると
閲覧できないかもしれません。
閲覧できない人はJBOSSをDLして付属ドキュメントの該当ページを参照してください。

Hibernate のアーカイブ(HAR)は多少汚いコードでHibernateを扱っても
安定して動作してくれるので(←根拠無し経験則)愛用していますが
HibernateContextと併用するとSessionを閉じなくてもトランザクションを
管理しなくても
OKなんてステキなドキュメントを発見してしまいました。
Session閉じ忘れてメモリーあふれさせた経験は私だけのものでしょうか??
しかもこの感じですとパフォーマンスも良さげです。

自分はcreateSQLQueryも使うので明示的に適切なタイミングでcommitしないと
結果が変わってきてたいへん困るのですがそのあたりどうなのかな??
いずれレビューしてみます。

なおこのHibernateContextは
${jboss_dir}/server/default/lib/jboss-hibernate.jar にあります。
JBoss4.0.4 で確認しました。
古いバージョンではどこにあるのか良く分かりませんでした(=_=;

| | コメント (0) | トラックバック (0)

2006年8月25日 (金)

Hibernate 3 で ネイティブSQLを使いまわす②Entity編

Hibernate 3 でネイティブなSQLを使いまわすのEntity取り出し編
なんだかSQLの書き方にクセがあったのでまとめたものをメモ

select {log.*} from mail_log_date as {log} where {log}.ad_id = :ad_id and DATE_TRUNC('month',{log}.recode_time) = :times

もしくは

select {log.*} from mail_log_date as log where log.ad_id = :ad_id and DATE_TRUNC('month',log.recode_time) = :times

このような感じ
select {log.*}でマップさせる
where句にプロパティを指定する場合は{log}.***の形式
あるいは{}で囲わない。

http://www.hibernate.org/hib_docs/reference/ja/html/querysql.html
↑には{log.***}の形式が載っていたがうまくいかなかった
仕様書のバージョンが違うのでしょうがない

◆正しく理解したい時はこの頁をよく読む
http://www.hibernate.org/hib_docs/v3/reference/en/html/querysql.html

■関連
http://bellks-tec.cocolog-nifty.com/blog/2006/08/hibernate3_nati_6f44.html


2006/09/29 追記

DATE_TRUNCはPostgreSQLの独自拡張ですね。
はい、MySQL方言使ったりPostgreSQL方言のっけたりばらばらでスイマセン

| | コメント (0) | トラックバック (0)

2006年8月 8日 (火)

Hibernate3 で Native なSQLを使いまわす

Hibernate便利なんだけど、エンティティ(データ本体)だけじゃなくて
データを分析した統計データを使用したいこともDBを使用したシステムなら多々ある。
Hibernateは時間に関係する関数がまったく無いからこのあたりが不便でならない。
という感想はかなりの人が持っていると思うのですがどうでしょうか?

Hibernate3でネイティブなSQLを使いまわす方法(createSQLQueryの用法)を紹介します。
よく紹介されているエンティティを取り出す方法ではなくて
統計データ等(マップされていないデータ)を取り出す方法です。
Hibernate3より前のバージョンでは関数の使い方が違うので要注意。

例1)
SQLQuery query = session.createSQLQuery("select distinct DATE_FORMAT(log.access_time,'%Y-%m-01') month from access_log log order by month desc");
query.addScalar("month",new org.hibernate.type.DateType());
List month_list = query.list();

上の例では架空のアクセスログテーブルに対してアクセスのある月を重複無しで取り出している。
ポイントは2行目addScalarのあたり、マップされていないデータの扱い方を通知する。
ちょっとトリッキーに返すデータの形式をStringからDate型に整形してマップしてみた。
month_listには java.sql.Date が格納されている。

例2)
SQLQuery query = session.createSQLQuery("select distinct DATE_FORMAT(log.access_time,'%Y-%m-01') month,DATE_FORMAT(log.access_time,'%D') day from access_log log order by month desc,day desc");
query.addScalar("month",new org.hibernate.type.DateType());
query.addScalar("day",new org.hibernate.type.IntegerType());
List date_list = query.list();

複数のデータを返すSQLの例
date_listには Object[] が格納されている。
Object[0] が java.sql.Date (例1と同じ値)に対応し Object[1]が日付値の Integerとなる。

注:MySQL使用…方言多様(?)

参考
http://www.powerdee.com/it/hibernate/hibernateQuery.html
http://www.hibernate.org/250.html

| | コメント (0) | トラックバック (1)

2006年4月27日 (木)

『Could not synchronize database state with session』に苦しんだ(改)

アクセスが多い記事なのでまとめて読みやすくしてみました。
オリジナルは
http://bellks-tec.cocolog-nifty.com/blog/2006/02/hibernatecould__0416.html

Hibernateを扱い始めてまもなく難解なエラーが発生

エラーメッセージ:
Could not synchronize database state with session

http://www.hibernate.org/hib_docs/reference/en/html/quickstart.html

上記ページにあるHibernateUtilクラスをあんまり理解せずに流用していたのが主な原因
このクラスの処理はThreadLocalを使用しているのが特徴でThread処理で
一回のみSessionが生成され、あとの呼び出しでは一度生成されたSessionが
使いまわされる仕組みだ。

エラーが出たのは、途中の処理でSessionを閉じていたこと。
その後Sessionを新規で作成しているつもりで

HibernateUtil#currentSession()

を呼び出していたが、ここでは予想と違い閉じられたSessionが
使いまわされて返されていた。
閉じられたSessionのメゾットを呼び出した時点でエラーが発生したということ。

エラーの回避としてはThreadLocalを使用しないようにHIbernateUtilを改造して一件落着(^^)v
パフォーマンス的にはThreadLocalのほうが良いであろうが…

| | コメント (0) | トラックバック (1)

2006年2月 4日 (土)

Hibernateで『Could not synchronize database state with session』に苦しんだ

2006/04/27 この記事はアクセスが多かったので読みやすく書き直しましたコチラもどおぞ
http://bellks-tec.cocolog-nifty.com/blog/2006/04/could_not_synch_ed05.html

HibernateでどうにもDBコネクションの使いまわしがうまくいかない。
DBCPで回収できない接続が残るのかDB接続数がパンクしてしまう。
いろいろと細かい修正を行っているうちになにやらエラーが出てきた

Could not synchronize database state with session

分からん...
更新時にのみでてきたのでどの改造が影響したのかサッパリ
問題解決でCVSにコミットしようと思っていたからCVSにも経過は無し(; ;)

いろいろ検証してゆくと。
何気に更新可能な永続オブジェクトもあることが判明

違いをひたすら探す。
  |
(数時間経過)
  |
全部じゃないがリレーション系が弱い傾向がある…
細かい処理を検証
  |
(数時間経過)
  |
データの取得が入れ子処理になっているところでエラーが起こる。
原因発見!!

http://www.hibernate.org/hib_docs/reference/en/html/quickstart.html

にあるHibernateUtileクラスをよく理解せずに使っていたことが主な原因
今回Tree階層になっているカテゴリーに分類された品物のDBを扱っていた。
Treeの全容を表示する(ルートまで親カテゴリーを表示する)ユーティリティクラスを
作成し使用していたが、この中でHibernateUtile#closesSession()を呼び出していた。

Sessionを開始

商品オブジェクトを取得

商品オブジェクトのカテゴリー全容をユーティリティクラスから取得
(実はここでHibernateUtile#closesSession()が呼び出されSessionがクローズされてしまう)

商品オブジェクトを変更しSession#update
(既に閉じられているSessionのためエラー発生)

Sessionを終了

ということ、設計をひたすら変更し対応(^^;
Threadで使いまわさなくてもいいからSessionFactoryのみ
使いまわすようにしてSessionは毎回作成したほうが安全かもしれない

| | コメント (0) | トラックバック (1)

JBossでHibernateを動かすとき最低限追加設置が必要なJar

『TomcatでHibernateを動かすとき最低限追加設置が必要なJar』
↑↑のJBoss版記事

単純な機能のみを使う場合

ehcache-1.1.jar

2007/01/18 追記 JBoss 4.0.4 GA 以降 ehcache-1.2.3.jar

だけでよい
TreeCacheを使用する場合追加して

jboss-system.jar
jboss-common.jar
jboss-jmx.jar
concurrent-1.3.2.jar

が必要

| | コメント (0) | トラックバック (0)

TomcatでHibernateを動かすとき最低限追加設置が必要なJar

Hibernateの配布ファイル付属のドキュメントにはrequireなjarが
用途別に書いてあるのだが、正直でどれを設置すればいいの?といつも迷う
Tomcatで最低限これを設置したとき動いたという感じのjarのリスト
自分で使用しているぶんには問題ないが使えない機能があるかもしれない
心配な人はしっかりドキュメントを読もう

使用しているHibernateのバージョンは3.0.5

jta.jar
asm.jar
asm-attrs.jar
commons-collections-2.1.1.jar
log4j-1.2.9.jar

#何故か日本語が文字化けるlog4jを設置していればはずしても動いたので後にはずす
(commons-logging-1.0.4.jar)

dom4j-1.6.jar
antlr-2.7.5H3.jar
ehcache-1.1.jar
cglib-2.1.jar

設置した位置は
/share/lib

コッチに設置するほうがスマートかもしれない
/webapps/hoge/WEB-INF/lib

| | コメント (0) | トラックバック (1)

MiddlegenIDEで簡単EJB/Hibernate生成

EJB/HibernateをGUIでDBから作成できる便利なMiddlegen

これをEclipse上から使用できるようにしたのがMiddlegenIDE

Oracle JDeveloperでGUIでEJBが作成出来たのがとても便利で
何とかEclipseでできんのかなぁと思い探し当てました。
なかなか便利で感心しています。

2006-11-08
  以下で紹介しているページはなくなっていました。
  <2006-11-08現在確認できたURL>
  Middlegen http://boss.bekk.no/boss/middlegen/
    ダウンロード http://sourceforge.net/project/showfiles.php?group_id=36044
  またeclipse 3.2に Middlegen IDE 1.3.2をインストールしたところ
    必要なjarはant build時に自動でコピーされるようになっていました

MiddlegenIDE
http://ultimania.org/middlegenide/

セットアップのポイントは必要なjarがたくさんあるということ
別途Middlegenをダウンロード解凍しておきEclipseの
パスに通しておくとよい。
必要なJarは上記URLでjarsとなっている画像を参照のこと

◆使用法
バージョンは古いですが以下のページに良くまとまっています。
http://www.atmarkit.co.jp/fjava/rensai3/eclipseplgn03/eclipseplgn03_3.html

◆少し裏技的Tips

2006-11-08 新しい情報を確認したところデフォルトで作成できるようになっていました

◇EJB(cmp)を生成する

MiddlegenIDEはEJB(cmp)に対応していないことになっているが
MiddlegenをEclipseから起動させるだけのものなので
当然作成することが可能なはずである。
いろいろ試しているうちにMiddlegenとMiddlegenIDEのファイルを比べて
『middlegen-entitybean-plugin-2.1.jar』
がライブラリに足りないことに気が付く。
これをたしてみると普通に作成することに成功した。
足す位置は
[eclipseインストールディレクトリ]\plugins\net.sf.middlegen_2.1.90\lib

◇EJB生成時余計なファイルを作らせない

MiddlegenIDEでEJBを生成するとXdocletが独自の設定で自動的に起動し
必要のないアプリケーションサーバー用の配布ディスクリプトなど
余計なファイルまで作成したりして大変厄介だったりする。
Xdocletの起動スクリプトはVelocityで生成される、
テンプレートは編集が可能なのであらかじめ都合のよいように編集しておく
テンプレートの位置は

[eclipseインストールディレクトリ]\plugins\org.ultimania.middlegenide_1.3.2\resource\template\build-ejb.xml.vm

同フォルダにはhibernate用のテンプレートもあるので必要なら編集してもよいかもしれない。

2006-11-08 追記
<動作確認>

 eclipse 3.2に2006-11-08時点で最新のバージョン1.3.3をインストールしてみたところ
  成城に動作しなかった。
  ひとつ古いバージョン1.3.2をインストールしたところ正常に動作した。
 

| | コメント (0) | トラックバック (0)