一つ以上の項目がPKとなったケースでHibernateはどう設定すればいいのかを説明します。 ずいぶん昔のメモになります。

こんなテーブルがあるとします。

create table Account (
	code varchar(255) not null,
	number integer not null,
	description varchar(255),
	primary key (code, number)
);

PKは’code’と’number’です。

方法は三つあります

まずPKを表すクラスを作ります。PKクラスは以下の条件を満足しなければなりません。

  • publicクラス
  • デフォルトのコンストラクタ
  • シリアライズを実装
  • hashCode()とequals()を実装

そしてエンティティクラスは以下の三つの方法のうちどれかで実装します。

  • PKクラスを@Embeddableアノテーションで記述し、エンティティクラスのプロパティとして書いて@Idとマーク
  • PKクラスをエンティティクラスにプロパティとして書いて@EmbeddableIdとマーク
  • PKを表す全ての項目をエンティティクラスのプロパティとして登録し@Idとマーク

それぞれのソースコードをリストします。

一番目@Embeddable

ここはAccountとそのPKを表すクラスAccountPkを作成しました。 メリットはPKクラスを再利用できるところです。 もっとも自然的なアプローチだそうです。

package sample.annotations;

import java.io.Serializable;

import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.Id;


@Entity
public class Account {
	private String description;
	private AccountPk id;

	public Account(String description) {
		this.description = description;
	}

	protected Account() {
	}

	@Id
	public AccountPk getId() {
		return this.id;
	}

	public String getDescription() {
		return this.description;
	}

	public void setId(AccountPk id) {
		this.id = id;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	@Embeddable
	public static class AccountPk implements Serializable{
		private String code;
		private Integer number;

		public AccountPk() {
		}

		public String getCode() {
			return this.code;
		}

		public Integer getNumber() {
			return this.number;
		}

		public void setNumber(Integer number) {
			this.number = number;
		}

		public void setCode(String code) {
			this.code = code;
		}

		public int hashCode() {
			int hashCode = 0;
			if (code != null)
				hashCode ^= code.hashCode();
			if (number != null)
				hashCode ^= number.hashCode();
			return hashCode;
		}

		public boolean equals(Object obj) {
			if (!(obj instanceof AccountPk))
				return false;
			AccountPk target = (AccountPk) obj;
			return ((this.code == null) ? (target.code == null) : this.code
					.equals(target.code))
					&& ((this.number == null) ? (target.number == null)
							: this.number.equals(target.number));
		}
	}
}

検証するクラスを作成しました。

package sample.annotations;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

import sample.annotations.Account.AccountPk;

public class TestAccount {
	public static void main(String** args) {
		SessionFactory sessionFactory = new AnnotationConfiguration()
				.configure().buildSessionFactory();
		Session session = sessionFactory.openSession();
		session.beginTransaction();

		Account account = new Account("This is the first type.");

		// construct pk value
		AccountPk accountPk = new AccountPk();
		accountPk.setCode("kinopyo001");
		accountPk.setNumber(12345);
		// set pk
		account.setId(accountPk);

		// save
		session.save(account);
		session.getTransaction().commit();
		System.out.println("Commit");

		// load
		List list = session.createQuery("from Account").list();
		Iterator i = list.iterator();
		while (i.hasNext()) {
			Account a = (Account) i.next();
			System.out.println("code: " + a.getId().getCode() + ", number: "
					+ a.getId().getNumber() + "  Description: "
					+ a.getDescription());
		}
		session.close();

	}
}

設定が正しければこんなログが出るはずです。

Commit
code: kinopyo001, number: 12345  Description: This is the first type.

二番目@EmbeddableId(抜粋)

@EmbeddedId
public AccountPk getId() {
	return this.id;
}

三番目@IdClass(抜粋)

@Entity
@IdClass(Account.AccountPk.class)
public class Account {

	private String description;
	private String code;
	private Integer number;

	public Account(String description) {
		this.description = description;
	}

	protected Account() {
	}

	@Id
	public String getCode() {
		return this.code;
	}

	@Id
	public Integer getNumber() {
		return this.number;
	}

	public String getDescription() {
		return this.description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public void setNumber(Integer number) {
		this.number = number;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public static class AccountPk {
	// ...
}
#javascript #jquery

jQueryのappendやafterは全部DOM Manipulation、つまりDOM操作のメソッドであります。どう違うかは下記ソースコードを見るのが一番速いでしょう。

append(prepend,appendTo,prependTo)は要素内に、子供要素として貼り付ける

$('<span>span text</span>').appendTo(".chapter");

<div class="chapter"> ... </div>

組み立てた結果:

<div class="chapter">
	...
	<span>span text</span>
</div>

append、appendToは最後の子供要素として、prepend、prependToは最初の子供要素として挿入する感じです。

after(before,insertAfter,insertBefore)は要素の外、つまり同一のレベルで兄弟要素として貼り付ける

$('<span>span text</span>').insertAfter(".chapter");

組み立てた結果:

<div class="chapter">
	...
	<span>span text</span>
</div>

htmlタグがなければ無効

$('some text').appendTo(".chapter");

htmlに何の変更もないです。

#rails #ruby #mac #環境構築

MacにはデフォルトでRubyが入ってそうです。 ターミナルを開いてrails -vを叩いたらバージョン情報が出てきました。

ruby 1.8.7 (2009-06-08 patchlevel 173) *universal-darwin10.0*

そしてRubyだけじゃなくRailsも入ってましてびっくりしました。 すごいですねMacは。。。 て、railsのバージョンもrails -vで確認できますが、 デフォルトのバージョンは古いそうで下記のコマンドでアップグレードできます。

sudo gem update rails

するとこんなログ情報が出ます。

Updating installed gems
Updating rails
WARNING:  Installing to ~/.gem since /Library/Ruby/Gems/1.8 and
	  /usr/bin aren't both writable.
WARNING:  You don't have /Users/zolo/.gem/ruby/1.8/bin in your PATH,
	  gem executables will not run.
Successfully installed activesupport-2.3.8
Successfully installed activerecord-2.3.8
Successfully installed rack-1.1.0
Successfully installed actionpack-2.3.8
Successfully installed actionmailer-2.3.8
Successfully installed activeresource-2.3.8
Successfully installed rails-2.3.8
Gems updated: activesupport, activerecord, rack, actionpack, actionmailer, activeresource, rails
Installing ri documentation for activesupport-2.3.8...
Installing ri documentation for activerecord-2.3.8...
Installing ri documentation for rack-1.1.0...
Installing ri documentation for actionpack-2.3.8...
Installing ri documentation for actionmailer-2.3.8...
Installing ri documentation for activeresource-2.3.8...
Installing ri documentation for rails-2.3.8...
Installing RDoc documentation for activesupport-2.3.8...
Installing RDoc documentation for activerecord-2.3.8...
Installing RDoc documentation for rack-1.1.0...
Installing RDoc documentation for actionpack-2.3.8...
Installing RDoc documentation for actionmailer-2.3.8...
Installing RDoc documentation for activeresource-2.3.8...
Installing RDoc documentation for rails-2.3.8...

多少時間がかかります。 これでMacでのRuby開発の準備は完了です。

更新

gem update railsにsudoを付けないとこんなエラーが出るかも

WARNING:  Installing to ~/.gem since /Library/Ruby/Gems/1.8 and
	  /usr/bin aren't both writable.
WARNING:  You don't have /Users/paku-k/.gem/ruby/1.8/bin in your PATH,
	  gem executables will not run.
ERROR:  Error installing rails:
	bundler requires RubyGems version >= 1.3.6
#linux #環境構築

環境構築の記事でよく目にすると思いますが このsudoコマンド。 気になってて調べてみたんです。

sudo is a Terminal command used to execute a command as another user, by default, the root user.

あるコマンドを別のユーザとして実行する、デフォルトではルートユーザ、だそうです。

例えばルートユーザとしてあるアプリを実行したい時は:

sudo open ....
#linux #mac

ターミナルの起動

ターミナルはApplication/Utilitiesフォルダにあります。 CTRL+Spaceで直接Terminalを叩いても直接開けますので、 とても便利でずっとこれを使ってます。

基本コマンド

  • :ls
  • (Windowsのdirコマンドと同じ役割)list files and directories
  • :cd
  • change directory
  • :mk
  • ir:create a new directory
  • :cp
  • copy files or directories
  • :mv
  • move (rename) files or directories
  • :rm
  • remove files or directories

便利なコマンド

  • pwd 今のディレクトリのパスを返します。”/Users/(yourusername)”のような

  • open Finderでダブルクリックと同じ効果です。アプリを開くに使います。

  • ~ 波記号はHomeディレクトリのショートカットです。 例えばcd ~で叩くとデフォルトで”/Users/(yourusername)”ディレクトリに行きます。

ジョブコントロール

  • ps -ax これはActivity Monitorのコマンドバージョンと理解していいでしょう。 現在アクティブなアプリのリストを表示します。 よくgrepコマンドと組み合わせて使います。
ps -ax | grep http
ps -ax | grep mysql
  • kill ps -axの一番目の列はプロセスのIDの列です。 あるプロセスを強制的に終了させたい場合はID指定で”kill”できます。
kill xxx

上記の”xxx”はプロセスのIDです。

またアプリの名前がわかった場合はkillallコマンドが使えます。

killall Dock

大文字小文字は区別しますので、気おつけてください。

#database #java #spring #h2db

Springのコンテキストファイルにjdbc:embedded-databaseタグで type=”H2”でbeanを登録します。

jdbc:scriptタグで初期化時に実行したいSQLファイルを指定できます。 Sprintって、本当に便利ですね。

<jdbc:embedded-database id="dataSource" type="H2">
	<jdbc:script location="classpath:schema.sql"/>
	<jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>

ちなみにjdbcのnamespaceの登録も忘れずに。

xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc
		http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd">

H2以外でもHSQL、Derbyがサポートされています。