EJBコンポーネント以外でのコンテナ管理EntityManager取得方法

昨日から会社で苦戦していた、EJBコンポーネント以外でコンテナ管理のEntityManagerを取得するってのがやっとできたのでメモ。

①EJBコンポーネントの型に@persistenceContextアノテーションをつける。
(下記ではステートレスセッションbean)
@Stateless(name = “sampleEJB”, mappedName = “sampleEJB”)
@PersistenceContext(name = “sampleCtx”, unitName = “sampleUnit”)
public class StatelessSessionBean implements StatelessSession {
・・・・・・・
}

②persistence.xmlにpersistence-unitを指定
(下記では、データソースからDB接続を取得)

<persistence-unit name=”sampleUnit” transaction-type=”JTA”>

<jta-data-source>データソース名</jta-data-source>

<class>JPAクラスの完全修飾名</class>

</persistence-unit>

 

③使用したいモジュールからJNDIルックアップでEntityManagerを取得
EntityManager em = (EntityManager) context.lookup(“java:comp/env/sampleCtx”);
※java:comp/env/sampleCtxは、①でつけた@PersistenceContextのname属性をENC名で指定

参考URL:
http://download.oracle.com/docs/cd/B31017_01/web.1013/b28221/usclient005.htm#CIHCEHHG

アプリケーションディスクリプタを読む手順

バージョンチェックのために、アプリケーションディスクリプタ(アプリケーション名-app.xml)から現在使っているバージョンを取得したい。そんなときは、

var xml:XML = NativeApplication.nativeApplication.applicationDescriptor;
var ns:Namespace = xml.namespace();    //名前空間取得
var version:String = xml.ns::version;  //名前空間を指定して要素にアクセス

で取得できるみたいです。

名前空間のついたXMLを読むのはちょっと面倒ですね。

関連付けられているアプリケーションでファイルを開く

AIRアプリケーションから、例えばユーザーのデスクトップのディレクトリをエクスプローラで開こうと思ったら NativeProcess を使ってexplorer.exe を呼ぶしかないのかなと思っていました。

しかしそんなことはありませんでした。

var dir:File = File.desktopDirectory;
dir.openWithDefaultApplication();

完全に灯台下暗し! もっとよく入力補完のところでも見とくべきでした。

AIRアプリケーションで自動アップデート通知を出す

まずアップデート通知に使うxmlを用意する。

仮に update.xml とする

<?xml version="1.0" encoding="utf-8"?>
<update xmlns="http://ns.adobe.com/air/framework/update/description/1.0">
	<version>1.0.2</version>
	<url>http://www.example.com/hoge.air</url>
	<description><![CDATA[
ほげほげ
	]]></description>
</update>

あとは air.update.ApplicationUpdaterUI を使って update.xml をチェックしに行けばいいらしい。

private var updater:ApplicationUpdaterUI = new ApplicationUpdaterUI();

//creationComplete とかで呼ぶ
private function checkUpdate():void {
	updater.updateURL = "http://www.example.com/update.xml";
	updater.addEventListener(UpdateEvent.INITIALIZED, function(event:UpdateEvent):void {
		updater.checkNow();
	});
	updater.addEventListener(ErrorEvent.ERROR, function(event:ErrorEvent):void {
		trace(event.toString());
	});
	updater.isCheckForUpdateVisible = false;
	updater.initialize();
}

これでいいらしい。

wordpressでpermalinkがおかしくなった

wordpress 2.9.2 でpermalinkがおかしくなった。

あるwordpressのサイトでマルチサイト(っぽい)ことをやっているんだけど、このそれぞれのサイトでのURLが混同されちゃった。

ソースコードを追いかけてみたけど、イマイチはっきりしない。

関数の呼び出し順序は下記の通り

get_permalink() -> get_option(‘home’) -> get_option(‘siteurl’) => wp_load_alloptions() -> wp_cache_get(‘alloptions’, ‘options’) -> $wp_object_cache->get(‘alloptions’, ‘option’)

最後の$wp_object_cacheはobject_cache.phpを利用しているのでその中のget()が呼ばれている。

ここまでたどったけどすべての戻り値でおかしいほうのブログのURLが返されてた。

ここで中のmemcacheのデータを確認。

memcacheのデータを確認するのって面倒なので以前に利用したコードを利用する。

このとき対象となるキーは “1options:alloptions” だった。

wp_cache_get()とかwp_object_cache->get()の引数にもある “alloptions, options”ってのがmemcacheのキーの後ろ側らしい。前にある2ってのはブログID。

今回の問題では複数のブログ、 ブログ1, ブログ2, ブログ3ぐらいまであって、そのうちのブログ1のキャッシュデータにブログ2のデータが上書きされてた。

ブログ3ではそのまま正しいデータが書かれていた。

該当するコードは過去にも見てたけどこれまでは普通に分割できてたはず。

 

ひとまずmemcacheデータを消してみる。データが存在しないときはたしか自動でDBサーバへクエリを投げて取りに行ってくれた気がするので。

消したら直ったような気がした。

NativeMenuの使い方

var menu:NativeMenu = new NativeMenu();                 //入れ物
var item1:NativeMenuItem = new NativeMenuItem("hoge");  //アイテム
var item2:NativeMenuItem = new NativeMenuItem("fuga");

menu.addItem(item1);
menu.addItem(new NativeMenuItem("", true));  //仕切り
menu.addItem(item2);

と準備しておいて、あとは NativeWindow.menu に menu を渡してウィンドウのメニューとして使ったり、マウスイベントなんかで menu.display(stage, event.stageX, event.stageY) を呼んでポップアップ表示させたりして使えばOK。他にはシステムトレイのアイコンクリック時のメニューもこれで。