Hibernateで以下の例外が出る場合は、リレーションシップにあるエンティティ(クラス)のhashCode、equalsメソッドがどう実装されているか見直しましょう。
Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session:
2013年11月23日土曜日
jQueryの:notセレクタは何かと便利
HTMLのエレメントでclassに何種類か設定してある場合、jQueryの:notセレクタを使ってやると便利。
<div class="someA someB" />
<script>
var divs = $('.someA:not(someB)');
</script>
みたいな感じ。
<div class="someA someB" />
<script>
var divs = $('.someA:not(someB)');
</script>
みたいな感じ。
MySQLの作成日と更新日のカラム生成の設定が分かりやすかった記事
MySQLのテーブルでレコードの増減が頻繁に起こるテーブルは作成日と更新日のカラムを作成したりすると便利です。ただ、コードでいちいち書くの面倒くさいからデータベース側で設定できないか調べていると便利な記事を見つけました。
ポイントは、
http://www.marcus-povey.co.uk/2013/03/11/automatic-create-and-modified-timestamps-in-mysql/
ポイントは、
- Timestamp型はレコードに更新があれば自動更新してくれる。ただし、テーブルにつき1つ。
- 作成日カラムはDatetime型にする。
- レコードがINSERTされたら作成日を設定してやるトリガーを用意。
こんなとこでした。あとの注意点は作成日のデフォルト値かな。
http://www.marcus-povey.co.uk/2013/03/11/automatic-create-and-modified-timestamps-in-mysql/
HibernateのAutomatic State Detection
まだちょっとsaveOrUpdateとmergeの違いを分かっていないのですが、基本的なところでsaveする時とupdateする時の違いは、エンティティのID(主キー)がnullかどうかで自動制御しているようです。ちょっと、ここもハマった。
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/objectstate.html#objectstate-saveorupdate
// in the first session Cat cat = (Cat) firstSession.load(Cat.class, catID); // in a higher tier of the application Cat mate = new Cat(); cat.setMate(mate); // later, in a new session secondSession.saveOrUpdate(cat); // update existing state (cat has a non-null id) secondSession.saveOrUpdate(mate); // save the new instance (mate has a null id)
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/objectstate.html#objectstate-saveorupdate
HTMLのhiddenを使わずして値をエレメントに保持する
HTMLのページで、例えばテーブルの列のIDなどを保持したい場合にhiddenなどのタグを使うと面倒くさいので、エレメントその物にデータ(ID)を保持できるのが便利。
DIVのdata-value属性を使ってやると、jQueryだとdata()で取得できる。
<div class="comment" data-value="64">
var value = $('[div selector]').data('value');
楽ちん楽ちん。
jQueryでAjaxを使ったDataTableでちょっとハマったとこ
jQueryのDatableのプラグインで、Ajaxを使ってサーバーサイドからデータを取るページを作るのに若干ハマったとこをメモ書き。
ページでテーブルが表示されてから、何かのアクションを起こしてテーブルをサーバーサイドのデータで再描画する時、sEchoというパラメータに注意。あまり注意してなかったので、適当に1と設定していたのですが、これは描画リクエストがある度に更新してやらないと、クライアントサイドで再描画が起こらない。(キャッシュしてるのかな?)
という事なので、バックエンドではインクリメントをして返してやると、ちゃんとテーブルを描画してくれました。
string | sEcho | An unaltered copy of sEcho sent from the client side. This parameter will change with each draw (it is basically a draw count) - so it is important that this is implemented. Note that it strongly recommended for security reasons that you 'cast' this parameter to an integer in order to prevent Cross Site Scripting (XSS) attacks. |
ラベル:
AJAX,
DataTables,
jQuery
2013年11月21日木曜日
JPAとHibernateのCascadeTypeにハマりました。。。
Hibernateでエンティティの関連性にCascadeTypeを使うと、データ取得だけとか、更新もするとか、いろいろ指定できるはずなのですが、できない??結構ハマったのですが、いろいろと調べると参考になるサイトに、JPAとHibernateでそれぞれCascadeTypeのアノテーションがあり、HibernateのSessionを使っているとJPAのCascadeTypeでは予測した挙動で動いてくれないようです。これはハマる!!
org.hibernate.annotations.CascadeType
javax.persistence.CascadeType
は違う!!
JPA
@OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST,CascadeType.MERGE }, mappedBy = "stock")
Hibernate
@OneToMany(fetch = FetchType.LAZY, mappedBy = "stock") @Cascade({CascadeType.SAVE_UPDATE})
それにしても、@OneToManyはjavax.persistenceで、@Cascadeはorg.hibernate.annotations、ややこしい。。。
http://docs.oracle.com/javaee/6/api/javax/persistence/CascadeType.html
SpringのControllerでリクエストパラメーターが多い時はMultiValueMapを使う
SpringのControllerでリクエストパラメーターをたくさん受け取る場合、org.springframework.util.MultiValueMapを使うと便利。
パラメーター(キー)がユニークな場合は、MultiValueMap<String,String>なんでgetFirst(K key)で、パラメーター(キー)に紐付けられた値が複数ある場合は、MultiValueMap<String,List<String>>をget(Object key)で取れる。
http://docs.spring.io/spring/docs/3.1.4.RELEASE/javadoc-api/org/springframework/util/MultiValueMap.html
http://stackoverflow.com/questions/16355168/spring-mvc-requestparam-as-map-get-url-array-parameters-not-working
パラメーター(キー)がユニークな場合は、MultiValueMap<String,String>なんでgetFirst(K key)で、パラメーター(キー)に紐付けられた値が複数ある場合は、MultiValueMap<String,List<String>>をget(Object key)で取れる。
http://docs.spring.io/spring/docs/3.1.4.RELEASE/javadoc-api/org/springframework/util/MultiValueMap.html
http://stackoverflow.com/questions/16355168/spring-mvc-requestparam-as-map-get-url-array-parameters-not-working
2013年11月16日土曜日
HTMLのformをjQueryでsubmitさせない方法
<form id="someform">....</form>
<script>
$('#someform').submit(function(event){
event.preventDefault();
});
</script>
event.preventDefault()はイベント制御には何かと便利。
http://api.jquery.com/event.preventDefault/
<script>
$('#someform').submit(function(event){
event.preventDefault();
});
</script>
event.preventDefault()はイベント制御には何かと便利。
http://api.jquery.com/event.preventDefault/
jQueryとAjaxを使ってフォームのデータを送信する時、たくさんのエレメントがあると面倒くさいのでserialize()を使う。
<form id="someForm">...</form>
<script>
$.ajax({
url: 'someurl',
type: 'post',
data: $('#someForm').serialize()
}) ;
</script>
こんな感じ。
http://stackoverflow.com/questions/5004233/capture-all-of-the-forms-data-and-submit-it-to-a-php-script-jquery-ajax-post
<script>
$.ajax({
url: 'someurl',
type: 'post',
data: $('#someForm').serialize()
}) ;
</script>
こんな感じ。
http://stackoverflow.com/questions/5004233/capture-all-of-the-forms-data-and-submit-it-to-a-php-script-jquery-ajax-post
ラベル:
AJAX,
JavaScript,
jQuery
JUnit4で特定のテストケースを実行しない方法
これは非常に簡単で@Testで指定したテストケースを@Ignoreで無視しておいてと教えてあげればいい。
http://junit.sourceforge.net/javadoc/org/junit/Ignore.html
http://junit.sourceforge.net/javadoc/org/junit/Ignore.html
HibernateのsaveOrUpdateについて
テーブルにレコードを追加、もしくは既にあるレコードを更新する場合にSessionのsaveOrUpdateを使っているのだが、INSERTかUPDATEかの挙動はプライマリーキーがテーブルに存在しているかどうかで決定されるようだ。nullであればもちろん追加される。
しかしながら、updateやsaveOrUpdateやmergeなどがあって、まだまだ違いが不明。ここは要する調査。
MySQLのselect文で連番を自動生成する方法
変数を使ってインクリメントするだけ。
http://stackoverflow.com/questions/15930514/mysql-auto-increment-temporary-column-in-select-statement
mysql> set @n=0;
mysql> select @n:=@n+1 serial_number from table1;
http://stackoverflow.com/questions/15930514/mysql-auto-increment-temporary-column-in-select-statement
MySQLのselectからinsertする構文
insert into table1
select a, b, c from table2 where id=?
みたいな感じ。
http://stackoverflow.com/questions/15523597/mysql-insert-into-values-and-select
select a, b, c from table2 where id=?
みたいな感じ。
http://stackoverflow.com/questions/15523597/mysql-insert-into-values-and-select
HTMLのformのエレメントを一括で無効化する方法
<fieldset></fieldset>でdisabled属性を使えば良い。
http://www.w3schools.com/tags/tag_fieldset.asp
<form>
<fieldset>
<legend>Personalia:</legend>
Name: <input type="text"><br>
Email: <input type="text"><br>
Date of birth: <input type="text">
</fieldset>
</form>
<fieldset>
<legend>Personalia:</legend>
Name: <input type="text"><br>
Email: <input type="text"><br>
Date of birth: <input type="text">
</fieldset>
</form>
http://www.w3schools.com/tags/tag_fieldset.asp
2013年11月15日金曜日
MySQLで外部キー制約を一時的に解除する方法
MySQLで外部キー制約を持ったテーブルの定義を変更したい場合、何かと制約でエラーが出て変更できない面倒くさい状況が出るので回避策。
> SET foreign_key_checks=0 ------> 外部キー制約を解除
> SET foreign_key_checks=1 ------> 外部キー制約を有効
http://stackoverflow.com/questions/2300396/force-drop-mysql-bypassing-foreign-key-constraint
> SET foreign_key_checks=0 ------> 外部キー制約を解除
> SET foreign_key_checks=1 ------> 外部キー制約を有効
http://stackoverflow.com/questions/2300396/force-drop-mysql-bypassing-foreign-key-constraint
OS Xのターミナルでカーソルを先頭、最後尾に戻すショートカット
ctrl + a -----> front
ctrl + e -----> end
http://apple.stackexchange.com/questions/8928/move-to-start-of-line-in-terminal-app
ctrl + e -----> end
http://apple.stackexchange.com/questions/8928/move-to-start-of-line-in-terminal-app
2013年11月8日金曜日
HibernateでLocalSessionFactoryBeanを複数設定した場合の使いわけ
Hibernateで複数のデータベースに接続したい場合、LocalSessionFactoryBeanを複数設定ファイルに書きますが、ソースコードのDAO側でどうやって切り分けるのかが分からない。
<bean id="sessionFactoryA" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="configLocation">
<value>/WEB-INF/A.cfg.xml</value>
</property>
</bean>
<bean id="sessionFactoryB" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="configLocation">
<value>/WEB-INF/B.cfg.xml</value>
</property>
</bean>
調べてみると、意外にも簡単で@Qualifierアノテーションでidを指定するだけでOK。
@Repository
public class SomeDaoImpl implements SomeDao
{
@Autowired
@Qualifier(value="sessionFactoryA")
private SessionFactory _sessionFactory;
こんな感じ。簡単簡単。
2013年11月7日木曜日
とりあえずHibernateのエンティティマッピングの書き方をすぐ忘れてしまうので。。。
とりあえずHibernateのエンティティマッピングの書き方をすぐ忘れてしまうので、一番すっきりとしていて分かりやすいお手本のリンクをメモっておくことにした。
http://en.wikibooks.org/wiki/Java_Persistence/OneToOne
http://en.wikibooks.org/wiki/Java_Persistence/OneToOne
Hibernateでカラムのソートの昇順・降順を指定するには@OrderByを使う
@OrderColumnの落とし穴 でHibernateのエンティティで一対多の関係を持ったコレクションのフィールドで@OrderColumnを使用した場合に、java.util.Listがnullオブジェクトを追加してしまうのでjava.util.Setを使う事にしました。
じゃあそのコレクションのソート降順・昇順の指定はどうなるんだ?という事ですが、@OrderByで指定できるようです。中身は@OrderBy("ID ASC")もしくは@OrderBy("ID DESC")のように、ここはシンプルに指定できます。また、なぜか@OrderColumnは指定する必要が無い事に気づきました。なんで???
またもやHibernateの未知なブラックボックスです。どうやって@OrderByと@OrderColumnを使い分けるのだろう??
http://stackoverflow.com/questions/11433195/hibernate-orderby-vs-ordercolumn-to-maintain-the-order-of-a-collection
じゃあそのコレクションのソート降順・昇順の指定はどうなるんだ?という事ですが、@OrderByで指定できるようです。中身は@OrderBy("ID ASC")もしくは@OrderBy("ID DESC")のように、ここはシンプルに指定できます。また、なぜか@OrderColumnは指定する必要が無い事に気づきました。なんで???
またもやHibernateの未知なブラックボックスです。どうやって@OrderByと@OrderColumnを使い分けるのだろう??
http://stackoverflow.com/questions/11433195/hibernate-orderby-vs-ordercolumn-to-maintain-the-order-of-a-collection
2013年11月6日水曜日
とりあえずSpring+Hibernateで、DAO(データレイヤー)をJUnit4でテストする上で分かったことをまとめた。
まだ謎が多いので、分かった事をとりあえず一覧で。
- JUnit4で作ったクラスはAbstractTransactionalJUnit4SpringContextTestsを継承する。なぜ?
- spring-test.jarをpom.xmlに追加
- @RunWith(SpringJUnit4ClassRunner.class)をクラスレベルで書く。なぜ必要?
- @ContextConfiguration(locations={classpath:applicationContext.xml, classpath:hibernate.cfg.xml})をクラスレベルで書いて、設定ファイルを読み込む。この設定ファイルはクラスパスがとおった
- @TransactionConfiguratioをクラスレベルで書いて、defaultRollback=trueにする。ロールバック機能を使うと、データベースの状態をテスト前の状態にできるから便利。
- public void setDataSource(DataSource dataSource)をオーバーライドする。@Resource(name="dataSource")で設定ファイルで指定されているdataSourceを指定。
とにかくハマったとこ。。。
- Maven+Eclipse+WTPのファイル構造で設定ファイルをsrc/main/webapp/WEB-INF/は、クラスパス上にはならないので、src/test/resourceにテスト用の設定ファイルをtest-applicationContext.xml, test-hibernate.cfg.xmlのようにコピーした。もっと賢いやり方ないのかな。。。?ただ、WEB-INFから設定ファイルは動かしたくない。
- setDataSourceでtest-hibernate.cfg.xmlからDBのコネクション情報を指定してあげないといけないのだが、<session-factory></session-factory>の中に一括して書いてあるので、コネクション上に関してだけ抜き出して、applicationContext.xmlでdataSourceとして書きだした。
多くに共通してるとこは、設定の仕方が多い事が仇になっているということ。それがSpringとかHibernateの分かりにくいとこなのかなと実感。
参考にしたサイト:
http://stackoverflow.com/questions/2377763/abstracttransactionaljunit4springcontexttests-cant-get-the-dao-to-find-inserte
http://zakato.sblo.jp/article/50155918.html
http://java-cauldron.blogspot.com/2012/07/writing-junit4-tests-spring-30.html
http://mvnrepository.com/artifact/org.springframework/spring-test/3.2.4.RELEASE
http://kinoushi.blogspot.com/2008/08/abstracttransactionaljunit4springcontex.html
http://stackoverflow.com/questions/17220432/failed-to-load-applicationcontext-for-junit-test-of-spring-controller
http://junit.sourceforge.net/javadoc/org/junit/Assert.html
http://intink.blogspot.com/2012/12/hibernate4spring-framework3.html
http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/testing.html#testcontext-fixture-di
http://forum.spring.io/forum/spring-projects/container/38874-transactional-junit4-controller-testing-with-multiple-datasources
http://forum.spring.io/forum/spring-projects/container/49585-how-to-get-contextconfiguration-using-web-inf-applicationcontext-xml
http://forum.spring.io/forum/spring-projects/web/97105-testing-problem-junit4-7-spring3-0-5-hibernate-3-3-2
ラベル:
Eclipse WTP,
Hibernate,
JUnit4,
Spring
@OrderColumnの落とし穴
@OrderColumnにハマった。。。Stackoverflowで書いてある状況と全く同じで、一対多の関連性のあるエンティティで多の方のエンティティにListを使っていると、何故かデータベースのテーブルに無いレコードがNullとしてListに入っている。????ここにハマった。
要するにListと使って多エンティティを保持すると、保持される順序を指定しないといけないので@OrderColumnを使うのだが、ここの仕様がややこしくてブラックボックス。
と、JavaDocを読んでててイマイチ不明なのだが、要するに@OrderColumnで指定するカラムがintの主キーで、400が一番若いIDだとすると、0~399まではテーブルには存在しないのだが、わざわざご丁寧に0~399までをnullオブジェクトとしてListの保存するわけだ。これが、contiguous (non-sparse) ordering. なんとお節介な機能だ。。。
そして、これを回避するにはList型でなくSet型を使って使うとnullオブジェクトが保持されなくなったのだが、どうもここはまだまだ奥が深そう。。。こういうところがHibernateの分かりにくいところ。。。
http://stackoverflow.com/questions/13307849/hibernate-returns-list-with-null-values-onetomany-annotation-with-list-type
http://docs.oracle.com/javaee/6/api/javax/persistence/OrderColumn.html
要するにListと使って多エンティティを保持すると、保持される順序を指定しないといけないので@OrderColumnを使うのだが、ここの仕様がややこしくてブラックボックス。
The order column must be of integral type. The persistence provider maintains a contiguous (non-sparse) ordering of the values of the order column when updating the association or element collection. The order column value for the first element is 0.※contiguous=切れ目の無い
と、JavaDocを読んでててイマイチ不明なのだが、要するに@OrderColumnで指定するカラムがintの主キーで、400が一番若いIDだとすると、0~399まではテーブルには存在しないのだが、わざわざご丁寧に0~399までをnullオブジェクトとしてListの保存するわけだ。これが、contiguous (non-sparse) ordering. なんとお節介な機能だ。。。
そして、これを回避するにはList型でなくSet型を使って使うとnullオブジェクトが保持されなくなったのだが、どうもここはまだまだ奥が深そう。。。こういうところがHibernateの分かりにくいところ。。。
http://stackoverflow.com/questions/13307849/hibernate-returns-list-with-null-values-onetomany-annotation-with-list-type
http://docs.oracle.com/javaee/6/api/javax/persistence/OrderColumn.html
HibernateのFetchTypeがLAZYとEAGERの違い
2つのエンティティ(テーブル)が一対多の関連性を持つ場合、どのタイミングで多のエンティティをロードしてあげるか、FetchTypeで2通りのやり方がある。
@OneToMany(fetch=FetchType.EAGER)
@OneToMany(fetch=FetchType.LAZY)
例えば、大学(Univeristy)というエンティティと学生(Student)というエンティティが一対多で関連付けられているとすると、Listのstudentsにデータをロードするタイミングとして、他のフィールド(id, name, address)と同じタイミングでロードするEAGERと、getStudents()などのオンディマンドでゲッターを呼ぶ場合にロードするLAZYのやり方がある。
@OneToMany(fetch=FetchType.EAGER)
@OneToMany(fetch=FetchType.LAZY)
例えば、大学(Univeristy)というエンティティと学生(Student)というエンティティが一対多で関連付けられているとすると、Listのstudentsにデータをロードするタイミングとして、他のフィールド(id, name, address)と同じタイミングでロードするEAGERと、getStudents()などのオンディマンドでゲッターを呼ぶ場合にロードするLAZYのやり方がある。
public class University {
private String id;
private String name;
private String address;
private List<Student> students;
// setters and getters
}
使い分けるポイントとしては、studentsにどれだけのデータがロードされるか、一度に全てロードする事が得策かどうかを考える必要がある。
http://stackoverflow.com/questions/2990799/difference-between-fetchtype-lazy-and-eager-in-java-persistence
登録:
投稿 (Atom)