JavaEE6をいじったときのメモ

## JPAについて
### JPAの参照系について
#### getResultList()の検索件数0件のときはどんな動きになる?
  
+  Size = 0のリストが帰ってくる感じです __(nullじゃないので注意)。__

####  entityの静的クエリはじぶんで追加してっていいんだよね?

+ なんか、普通に追加したら not foudと言われてしまった……

```
@NamedQueries({
:
@NamedQuery(name = "Customer.findByIdAndName", query = "SELECT c FROM Customer c WHERE c.customerId = :customerId AND c.name = :name")})
public class Customer implements Serializable {
:
```
```
Caused by: java.lang.IllegalArgumentException: NamedQuery of name: Customer.findByIdAndName not found.
``` 
結局、なんかデバッガ起動したりしてたら、何も変えずにちゃんと動きました。
意味がわかりませんが、コンテナ?が、追加した@NamedQueryをちゃんと認識するためのトリガーがあるのかな？？
___

### JPAの更新系について
+ トランザクションは
em.getTransactionでやればOKと思ってたけどこんなんでた。

```Java
public void updateCustomers(Customer customer){
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        em.merge(customer);
        tx.commit();
}
```
```
Caused by: java.lang.IllegalStateException: 
Exception Description: Cannot use an EntityTransaction while using JTA.
at org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper.getTransaction(JTATransactionWrapper.java:73)
```
なんか、JavaEEのトランザクションには種類があるっぽい。JTAトランザクションを使うべきところなのに、別のトランザクション使うなよってことかな？
以下のブログによると、persistence.xmlのなかで、RESOURCE_LOCAL/NON-JTA-DATA-SOURCE/JTA-DATA-SOURCEのいずれかが指定されているらしい。
http://nwing.knowd.co.jp/yamazaki/?q=node/118

> JTA-DATA-SOURCE
JTAを使って、トランザクションを管理します。
この場合、EntityManager#getTransactionによるトランザクション制御はできなくなります。トランザクションの制御はコンテナが行う(CMT - Contena Manged Transaction)ので、EJBの宣言性トランザクションを使用するか、または、UserTransactionを取得します。EJBと関連が強くなります。

> もし、JTA-DATA-SOURCEを使用しているにもかからずEntityManager#getTransactionから取得したEntitTransactionを使用すると、次の例外が発生します。

> Exception Description: Cannot use an EntityTransaction while using JTA.


ということみたい。で、JTAを利用する場合のトランザクションはUserTransactionでやってねということらしい。以下のようなかんじで書けばいいっぽい。

```
@Resource
UserTransaction utx;
：
public void updateCustomers(Customer customer){
		// 例外処理省略
        utx.begin();
        em.merge(customer);
        utx.commit();
}

```
……と思ったらやっぱりダメ。

```
Caused by: javax.naming.NameNotFoundException: java:comp/UserTransactionのルックアップは、コンテナで管理されるトランザクションBeanでは許可されません
 :
... 63 more
```
ほんとストレスたまるわ！！
　:
　:
####金魚本9章読んだら解決しました!!
EJB内でのトランザクションの管理方法は2種類あるらしい。

__CMT(コンテナ管理トランザクション)__

 トランザクションの開始、コミット、ロールバックをコンテナが自動管理

__BMT(Bean管理トランザクション)__

トランザクションの開始、コミット、ロールバックをBean内に記述(@TransactionManagementの指定が必要)。


より細かいトランザクション管理が必要(一つのメソッドで複数トランザクションを管理したい場合など)な時は、BMTを採用するといいみたい。
BMTでやる場合はこんな感じでやればOK。

```
@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class CustomerSessionBean {
 :
	@Resource
	UserTransaction utx;
 :
	public void updateCustomers(Customer customer){
		// 例外処理は省略
       utx.begin();
       em.merge(customer);
       utx.commit();
}
```


すごく簡単に言えば、CMTはトランザクションを自動的に管理してくれる(デフォルトはこっち)。
要するに、CMTでトランザクション管理してるから、BMTは許可できないよってことだったみたい。


## EJBについて
### @Injectの動きについて

#### @Inject, @Producer
以下参照
http://typea.info/blg/glob/2014/05/java-ee-4-java-ee-didependency-injection-cdicontexts-and-dependency-injection.html

#### @EJB
EJBのリモート&ローカル・インターフェース、インターフェースのないビュー参照を注入。
要するに、コンテナで動いてたりするEJB(セッションBean)への参照を注入している感じ。

#### @Resource
JDBCデータソース、セッション・コンテキスト、ユーザ・トランザクション等の参照を注入

#### @Remote, @Local
セッションBeanのリモートインターフェース、ローカルインターフェース(別のセッションBean用のインターフェース)を定義する。

```
@Local
public interface CustomerManegerLocal {
    List<Customer> getCustomers();
    List<Customer> getCustomersById(int id);
    void updateCustomers(Customer customer);
}

@Remote
public interface CustomerManegerRemote {
    List<Customer> getCustomers();
    List<Customer> getCustomersById(int id);
    void updateCustomers(Customer customer);
}

// セッションBeanでの実装
@Stateless
public class CustomerManeger implements CustomerManegerLocal, CustomerManegerRemote {
 :
 :
}
```

呼び出しがわ

```
@Stateless
@Path("/customers")
public class CustomerSessionBean {
	// セッションBean間のローカル呼び出しなので、
    // CustomerManegerLocalに注入する必要がある。
    @Inject CustomerManegerLocal cm;
 :
 :
```

## その他
### 変なビルド失敗について
なんかMavenで新しくプロジェクトを作ってみたら、以下のエラーがでてデプロイできなくなった。

```
Exception Description: Entity name must be unique in a persistence unit. Entity name [MicroMarket] is used for the entity classes [com.mycompany.customermng.MicroMarket] and [com.mycompany.customermng.entities.MicroMarket].
```
なんかパッケージ名を変えたときのゴミが残ってたみたい。消去してビルドをやったら上手くいった。