サンプルプロジェクトはこちら fileS2DaoExam.zip
(ビルドや実行には Eclipse + m2plugin が必要です)

はじめに

S2Dao-Tiger の概要

練習用DBの作成

練習用プロジェクトの作成

プロジェクト構成

m2plugin で、Maven Project を作成し、次のように資産を配置する

s2dao3.png
src/main/java/com/snail/exam/s2daoJavaソースファイルを格納(S2Containerに、走査するパッケージ名を指定するので、S2Containerを使ってインスタンス化するものは同一パッケージにする)
src/main/resources/diconファイルなどの設定ファイルを格納
pom.xml依存ライブラリを定義する

diconファイルについて

pom.xml について

<?xml version="1.0" encoding="UTF-8"?><project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>S2DAOExam</groupId>
  <artifactId>S2DAOExam</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <description></description>
  <build>
    <finalName>S2DAOExam</finalName>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <repositories>
    <repository>
      <id>maven.seasar.org</id>
      <name>The Seasar Foundation Maven2 Repository</name>
      <url>http://maven.seasar.org/maven2</url>
    </repository>
    <repository>
      <id>maven2-repository.dev.java.net</id>
      <name>Java.net Maven 2 Repository</name>
      <url>http://download.java.net/maven/2</url>
    </repository>
    <repository>
      <id>maven-repository.dev.java.net</id>
      <name>Java.net Maven 1 Repository (legacy)</name>
      <url>http://download.java.net/maven/1</url>
      <layout>legacy</layout>
    </repository>
  </repositories>
  <dependencies>
    <dependency>
      <groupId>org.seasar.container</groupId>
      <artifactId>s2-tiger</artifactId>
      <version>2.4.32</version>
    </dependency>
    <dependency>
      <groupId>org.seasar.dao</groupId>
      <artifactId>s2-dao-tiger</artifactId>
      <version>1.0.49</version>
    </dependency>
    <dependency>
      <groupId>org.apache.derby</groupId>
      <artifactId>derby</artifactId>
      <version>10.3.1.4</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.3</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.15</version>
      <exclusions>
        <exclusion>
          <artifactId>jmxtools</artifactId>
          <groupId>com.sun.jdmk</groupId>
        </exclusion>
        <exclusion>
          <artifactId>jmxri</artifactId>
          <groupId>com.sun.jmx</groupId>
        </exclusion>
        <exclusion>
          <artifactId>jms</artifactId>
          <groupId>javax.jms</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>javax.transaction</groupId>
      <artifactId>transaction-api</artifactId>
      <version>1.1</version>
    </dependency>
    <dependency>
      <groupId>commons-beanutils</groupId>
      <artifactId>commons-beanutils</artifactId>
      <version>1.7.0</version>
    </dependency>
  </dependencies>
</project>

※ Derby のバージョンが 10.2 (JDK1.6.0_01付属) の場合には、Derby の <version> を変更する必要がある

Hello S2DAO。まずは顧客テーブルを読み出す。

CustomerBean?

package com.snail.exam.s2dao;

import java.sql.Timestamp;

import org.seasar.dao.annotation.tiger.Bean;
import org.seasar.dao.annotation.tiger.Column;
import org.seasar.dao.annotation.tiger.Id;
import org.seasar.dao.annotation.tiger.IdType;
import org.seasar.dao.annotation.tiger.Ids;

@Bean(table = "CUSTOMER_TBL",timeStampProperty="onUpdate")
public class CustomerBean {
  private String pAddress;

  private int pCreditFacility;

  private double pDiscountRate;

  private long pId;
  
  private String pName;
  
  private Timestamp pOnCreate;

  private Timestamp pOnUpdate;

  @Column("ADDRESS")
  public String getAddress() {
    return pAddress;
  }

  @Column("CREDIT_FACILITY")
  public int getCreditFacility() {
    return pCreditFacility;
  }

  @Column("DISCOUNT_RATE")
  public double getDiscountRate() {
    return pDiscountRate;
  }

  @Column("ID")
  @Ids( {
    @Id(value = IdType.IDENTITY, dbms = "derby"),
    @Id(value = IdType.SEQUENCE, sequenceName = "SEQ_CUSTOMER", dbms = "oracle") })
  public long getId() {
    return pId;
  }

  @Column("NAME")
  public String getName() {
    return pName;
  }

  @Column("ON_CREATE")
  public Timestamp getOnCreate() {
    return pOnCreate;
  }

  @Column("ON_UPDATE")
  public Timestamp getOnUpdate() {
    return pOnUpdate;
  }

  public void setAddress(String address) {
    this.pAddress = address;
  }

  public void setCreditFacility(int creditFacility) {
    this.pCreditFacility = creditFacility;
  }

  public void setDiscountRate(double discountRate) {
    this.pDiscountRate = discountRate;
  }

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

  public void setName(String name) {
    this.pName = name;
  }

  public void setOnCreate(Timestamp onCreate) {
    pOnCreate = onCreate;
  }

  public void setOnUpdate(Timestamp onUpdate) {
    pOnUpdate = onUpdate;
  }
}

CustomerDao?

package com.snail.exam.s2dao;

import java.util.List;

import org.seasar.dao.annotation.tiger.Arguments;
import org.seasar.dao.annotation.tiger.Query;
import org.seasar.dao.annotation.tiger.S2Dao;
import org.seasar.dao.annotation.tiger.Sql;

@S2Dao(bean = CustomerBean.class)
public interface CustomerDao {

    /**
     * select処理. 
     * 返り値が、Entity でないとき、 SELECT COUNT(*) FROM CUSTOMER のように、
     * 値がひとつだけ返ってくる検索処理とみなされる。
     * 
     * @return 格納されている CUSTOMER の数
     */
    @Sql(value = "SELECT COUNT(ID) FROM CUSTOMER")
    int countAll();

    /**
     * delete処理.
     * delete処理は、delete,remove で始まるメソッド名にする。
     * 返り値は、int か void。
     * 
     * @param customer Customer
     * @return 更新された行数
     */
    int delete(CustomerBean customer);

    /**
     * select処理. 引数を指定しないと全件検索
     */
    List<CustomerBean> findAll();

    /**
     * select処理.
     * @Query アノテーション で、複雑なWHERER句 ORDER BY句を記述することが
     * できます。
     * 
     * @param id ID
     * @return Customer
     */
    @Query("ADDRESS LIKE ?%")
    List<CustomerBean> findByAddress(final String address);

    /**
     * select処理. 
     * 返り値が、Entity , List(List<Entity>) , Entity[] のとき Entity 
     * を返す検索処理とみなされる。 @Arguments アノテーションで、
     * 引数に対応する"列名"を 指定すると、単純な WHERE 句が生成される。
     * 
     * (引数の値がnullのときに検索条件に含めないような処理が 行われる)
     * 
     * @param id ID
     * @return Customer
     */
    @Arguments( { "ID" })
    CustomerBean findCustomer(final int id);

    /**
     * insert処理. 
     * insert処理は、insert,add,create で始まるメソッド名にする。
     * 返り値は、int か void。
     * 
     * @param customer Customer
     * @return 更新された行数
     */
    int insert(CustomerBean customer);

    /**
     * update処理.
     * update処理は、update,modify,store で始まるメソッド名にする。
     * 返り値は、int か void。
     * 
     * @param customer Customer
     * @return 更新された行数
     */
    int update(CustomerBean customer);

    /**
     * update処理.
     * メソッド名の末尾に UnlessNull がついている update 処理は
     * null でないフィールドのみ更新。 返り値は、int か void。
     * 
     * @param customer Customer
     * @return 更新された行数
     */
    int updateUnlessNull(CustomerBean customer);
}

S2DAOExam(CustomerDao? を使うプログラム)

package com.snail.exam.s2dao;

import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;

public class S2DAOExam {

  private static Log logger = LogFactory.getLog(S2DAOExam.class);

  public static void main(String[] args) {
    S2Container container = null;
    try {
      container = S2ContainerFactory.create("app.dicon");

      CustomerDao dao = (CustomerDao) container.getComponent(CustomerDao.class);

      List<CustomerBean> customerList = dao.findAll();
      
      for( CustomerBean bean : customerList ){
      	logger.debug(BeanUtils.describe(bean));
      }
      
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (container != null) {
        container.destroy();
      }
    }

  }
}

実行結果

S2Containerを作成します。path=app.dicon 
S2Containerを作成します。path=dao.dicon 
S2Containerを作成します。path=j2ee.dicon 
S2Containerを作成します。path=jta.dicon 
S2Containerを作成しました。path=jta.dicon 
S2Containerを作成します。path=jdbc.dicon 
S2Containerを作成します。path=jdbc-extension.dicon 
S2Containerを作成します。path=convention.dicon 
S2Containerを作成しました。path=convention.dicon 
S2Containerを作成しました。path=jdbc-extension.dicon 
S2Containerを作成しました。path=jdbc.dicon 
S2Containerを作成しました。path=j2ee.dicon 
S2Containerを作成しました。path=dao.dicon 
S2Containerを作成しました。path=app.dicon 
物理的なコネクションを取得しました 
論理的なコネクションを取得しました。tx=null 
論理的なコネクションを閉じました。tx=null 
物理的なコネクションを閉じました 
物理的なコネクションを取得しました 
論理的なコネクションを取得しました。tx=null 
論理的なコネクションを閉じました。tx=null 
物理的なコネクションを閉じました 
物理的なコネクションを取得しました 
論理的なコネクションを取得しました。tx=null 
SELECT CUSTOMER_TBL.CREDIT_FACILITY, CUSTOMER_TBL.DISCOUNT_RATE, 
  CUSTOMER_TBL.ON_CREATE, CUSTOMER_TBL.ON_UPDATE, CUSTOMER_TBL.ID, 
  CUSTOMER_TBL.ADDRESS, CUSTOMER_TBL.NAME FROM CUSTOMER_TBL 
論理的なコネクションを閉じました。tx=null 
物理的なコネクションを閉じました 
{id=1, onCreate=2008-11-24 17:33:35.821, address=メルキド, name=たびのどうぐや,
 class=class com.snail.exam.s2dao.CustomerBean, creditFacility=700,
 onUpdate=2008-11-24 17:33:35.821, discountRate=0.05000000074505806} 
{id=2, onCreate=2008-11-24 17:33:35.842, address=リムルダール, name=スーパー・リムル,
 class=class com.snail.exam.s2dao.CustomerBean, creditFacility=5000,
 onUpdate=2008-11-24 17:33:35.842, discountRate=0.10000000149011612} 
{id=3, onCreate=2008-11-24 17:33:35.86, address=ドムドーラ, name=ミリ金物店,
 class=class com.snail.exam.s2dao.CustomerBean, creditFacility=2500,
 onUpdate=2008-11-24 17:33:35.86, discountRate=0.0}

※適宜、編集・改行をしています

N:1マッピング。受注テーブルから顧客テーブルと商品テーブルを引く

Item Bean

まずは、Order Bean からマッピングされる Item Bean を作る。この Bean は、Customer Bean と同様に外部への参照はない。

package com.snail.exam.s2dao;

import org.seasar.dao.annotation.tiger.Bean;
import org.seasar.dao.annotation.tiger.Column;
import org.seasar.dao.annotation.tiger.Id;
import org.seasar.dao.annotation.tiger.IdType;
import org.seasar.dao.annotation.tiger.Ids;

import java.sql.Timestamp;

@Bean(table = "ITEM_TBL",timeStampProperty="onUpdate")
public class ItemBean {
  private int pFullPrice;

  private long pId;

  private String pName;

  private Timestamp pOnCreate;

  private Timestamp pOnUpdate;

  private int pStock;

  @Column("ID")
  @Ids( {
      @Id(value = IdType.IDENTITY, dbms = "derby"),
      @Id(value = IdType.SEQUENCE, sequenceName = "SEQ_ITEM", dbms = "oracle") })
  public long getId() {
    return pId;
  }

  @Column("NAME")
  public String getName() {
    return pName;
  }

  @Column("ON_CREATE")
  public Timestamp getOnCreate() {
    return pOnCreate;
  }

  @Column("ON_UPDATE")
  public Timestamp getOnUpdate() {
    return pOnUpdate;
  }

  @Column("FULL_PRICE")
  public int getPrice() {
    return pFullPrice;
  }

  @Column("STOCK")
  public int getStock() {
    return pStock;
  }

  public void setId(long id) {
    pId = id;
  }

  public void setName(String name) {
    pName = name;
  }
  public void setOnCreate(Timestamp onCreate) {
    pOnCreate = onCreate;
  }

  public void setOnUpdate(Timestamp onUpdate) {
    pOnUpdate = onUpdate;
  }
  public void setPrice(int price) {
    pFullPrice = price;
  }

  public void setStock(int stock) {
    pStock = stock;
  }

}

Order Bean

getter への @Relationアノテーションで、N:1 マッピングを行う。N:1 マッピングを行う場合に、getter/setter で扱うのは "1" 側をマッピングする Bean。

package com.snail.exam.s2dao;

import java.sql.Timestamp;

import org.seasar.dao.annotation.tiger.Bean;
import org.seasar.dao.annotation.tiger.Column;
import org.seasar.dao.annotation.tiger.Id;
import org.seasar.dao.annotation.tiger.Ids;
import org.seasar.dao.annotation.tiger.IdType;
import org.seasar.dao.annotation.tiger.Relation;

@Bean(table = "ORDER_TBL", timeStampProperty = "onUpdate")
public class OrderBean {
  private int pAmount;

  private CustomerBean pCustomerBean;

  private long pId;

  private ItemBean pItemBean;
  
  private Timestamp pOnCreate;

  private Timestamp pOnUpdate;

  private char pStatus;

  private int pTradePrice;

  @Column("AMOUNT")
  public int getAmount() {
    return pAmount;
  }

  @Relation(relationNo = 0, relationKey = "CUSTOMER_ID:ID")
  public CustomerBean getCustomerBean() {
    return pCustomerBean;
  }

  @Column("ID")
  @Ids( { @Id(value = IdType.IDENTITY, dbms = "derby"),
    @Id(value = IdType.SEQUENCE, sequenceName = "SEQ_PURCHASE", dbms = "oracle") })
  public long getId() {
    return pId;
  }

  @Relation(relationNo = 1, relationKey = "ITEM_ID:ID")
  public ItemBean getItemBean() {
    return pItemBean;
  }

  @Column("ON_CREATE")
  public Timestamp getOnCreate() {
    return pOnCreate;
  }

  @Column("ON_UPDATE")
  public Timestamp getOnUpdate() {
    return pOnUpdate;
  }

  @Column("STATUS")
  public char getStatus() {
    return pStatus;
  }

  @Column("TRADE_PRICE")
  public int getTradePrice() {
    return pTradePrice;
  }

  public void setAmount(int amount) {
    pAmount = amount;
  }

  public void setCustomerBean(CustomerBean CustomerBean) {
    pCustomerBean = CustomerBean;
  }

  public void setId(long id) {
    pId = id;
  }

  public void setItemBean(ItemBean ItemBean) {
    pItemBean = ItemBean;
  }

  public void setOnCreate(Timestamp onCreate) {
    pOnCreate = onCreate;
  }

  public void setOnUpdate(Timestamp onUpdate) {
    pOnUpdate = onUpdate;
  }

  public void setStatus(char status) {
    pStatus = status;
  }

  public void setTradePrice(int tradePrice) {
    pTradePrice = tradePrice;
  }

}

Order Dao

とりあえず、findAll() だけ

package com.snail.exam.s2dao;

import java.util.List;

import org.seasar.dao.annotation.tiger.S2Dao;

@S2Dao(bean = OrderBean.class)
public interface OrderDao {
  /**
   * select処理. 引数を指定しないと全件検索
   */
  List<OrderBean> findAll();
}

S2DAOExam2(Order Dao を使うプログラム)

package com.snail.exam.s2dao;

import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;

public class S2DAOExam2 {

    private static Log logger = LogFactory.getLog(S2DAOExam.class);

    public static void main(String[] args) {
        S2Container container = null;
        try {
            container = S2ContainerFactory.create("app.dicon");
            
            OrderDao dao = (OrderDao) container.getComponent(OrderDao.class);
            
            List<OrderBean> orderList = dao.findAll();
            
            for(OrderBean bean : orderList ){
            	StringBuilder sb = new StringBuilder();
            	sb.append("id=" + bean.getId());
            	sb.append(",item=" + bean.getItemBean().getName());
            	sb.append(",customer=" + bean.getCustomerBean().getName());
            	sb.append(",amount=" + bean.getAmount());
            	sb.append(",trade price=" + bean.getTradePrice());
            	sb.append(",full price=" + bean.getItemBean().getPrice());
            	logger.debug(sb.toString());
            }
            
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (container != null) {
                container.destroy();
            }
        }

    }
}

実行結果

 S2Containerを作成します。path=app.dicon   
 S2Containerを作成します。path=dao.dicon   
 S2Containerを作成します。path=j2ee.dicon   
 S2Containerを作成します。path=jta.dicon   
 S2Containerを作成しました。path=jta.dicon   
 S2Containerを作成します。path=jdbc.dicon   
 S2Containerを作成します。path=jdbc-extension.dicon   
 S2Containerを作成します。path=convention.dicon   
 S2Containerを作成しました。path=convention.dicon   
 S2Containerを作成しました。path=jdbc-extension.dicon   
 S2Containerを作成しました。path=jdbc.dicon   
 S2Containerを作成しました。path=j2ee.dicon   
 S2Containerを作成しました。path=dao.dicon   
 S2Containerを作成しました。path=app.dicon   
 物理的なコネクションを取得しました   
 論理的なコネクションを取得しました。tx=null   
 論理的なコネクションを閉じました。tx=null   
 物理的なコネクションを閉じました   
 物理的なコネクションを取得しました   
 論理的なコネクションを取得しました。tx=null   
 論理的なコネクションを閉じました。tx=null   
 物理的なコネクションを閉じました   
 物理的なコネクションを取得しました   
 論理的なコネクションを取得しました。tx=null   
 SELECT
   ORDER_TBL.ON_CREATE, ORDER_TBL.ON_UPDATE, ORDER_TBL.ID, ORDER_TBL.AMOUNT,
   ORDER_TBL.TRADE_PRICE, ORDER_TBL.STATUS, 
   customerBean.CREDIT_FACILITY AS CREDIT_FACILITY_0, 
   customerBean.DISCOUNT_RATE AS DISCOUNT_RATE_0, 
   customerBean.ON_CREATE AS ON_CREATE_0, 
   customerBean.ON_UPDATE AS ON_UPDATE_0, 
   customerBean.ID AS ID_0, 
   customerBean.ADDRESS AS ADDRESS_0, 
   customerBean.NAME AS NAME_0, 
   itemBean.ON_CREATE AS ON_CREATE_1, 
   itemBean.ON_UPDATE AS ON_UPDATE_1, 
   itemBean.ID AS ID_1, 
   itemBean.FULL_PRICE AS FULL_PRICE_1, 
   itemBean.STOCK AS STOCK_1, 
   itemBean.NAME AS NAME_1 
 FROM 
   ORDER_TBL 
   LEFT OUTER JOIN CUSTOMER_TBL customerBean ON ORDER_TBL.CUSTOMER_ID = customerBean.ID
   LEFT OUTER JOIN ITEM_TBL itemBean ON ORDER_TBL.ITEM_ID = itemBean.ID   
 論理的なコネクションを閉じました。tx=null   
 物理的なコネクションを閉じました   
 id=1,item=ぬののふく,customer=たびのどうぐや,amount=5,trade price=19,full price=20
 id=2,item=やくそう,customer=たびのどうぐや,amount=5,trade price=4,full price=5
 id=3,item=どくけしそう,customer=たびのどうぐや,amount=5,trade price=9,full price=10
 id=4,item=たいまそう,customer=たびのどうぐや,amount=5,trade price=95,full price=100

※適宜、編集・改行をしています

 

楽観ロック。Timestampチェックで、受注テーブルの競合を防ぐ。

楽観ロックの概要

S2Dao での楽観ロック

実験例

OrderDao?に更新メソッドを追加

package com.snail.exam.s2dao;

import java.util.List;

import org.seasar.dao.annotation.tiger.Arguments;
import org.seasar.dao.annotation.tiger.S2Dao;

@S2Dao(bean = OrderBean.class)
public interface OrderDao {
    List<OrderBean> findAll();
    
    @Arguments( { "ID" })
    OrderBean findOrder(final int id);
    
    int update(OrderBean order);
}

楽観ロック違反を起こす処理

package com.snail.exam.s2dao;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;

public class S2DAOExam3 {

  private static Log logger = LogFactory.getLog(S2DAOExam3.class);

  public static void main(String[] args) {
    S2Container container = null;
    try {
      container = S2ContainerFactory.create("app.dicon");

      OrderDao dao = (OrderDao) container.getComponent(OrderDao.class);

      // 1) Aさんが受注番号1の受注を紹介
      OrderBean beanA = dao.findOrder(1);
      
      // 2) Bさんが受注番号1の受注を紹介
      OrderBean beanB = dao.findOrder(1);
      
      // 3) Aさんが更新処理をする
      beanA.setStatus('1');
      
      int resA = dao.update(beanA);

      logger.debug("■■" + resA + "行上書きしました");
      
      // 4) Bさんが更新処理をする
      beanB.setStatus('1');
      
      int resB = dao.update(beanB);

      logger.debug("■■" + resB + "行上書きしました");
      
      
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (container != null) {
        container.destroy();
      }
    }
  }
}

実行結果

S2Containerを作成します。path=app.dicon
S2Containerを作成します。path=dao.dicon
S2Containerを作成します。path=j2ee.dicon
S2Containerを作成します。path=jta.dicon
S2Containerを作成しました。path=jta.dicon
S2Containerを作成します。path=jdbc.dicon
S2Containerを作成します。path=jdbc-extension.dicon
S2Containerを作成します。path=convention.dicon
S2Containerを作成しました。path=convention.dicon
S2Containerを作成しました。path=jdbc-extension.dicon
S2Containerを作成しました。path=jdbc.dicon
S2Containerを作成しました。path=j2ee.dicon
S2Containerを作成しました。path=dao.dicon
S2Containerを作成しました。path=app.dicon
物理的なコネクションを取得しました
論理的なコネクションを取得しました。tx=null
論理的なコネクションを閉じました。tx=null
物理的なコネクションを閉じました
物理的なコネクションを取得しました
論理的なコネクションを取得しました。tx=null
論理的なコネクションを閉じました。tx=null
物理的なコネクションを閉じました
物理的なコネクションを取得しました
論理的なコネクションを取得しました。tx=null
SELECT 
  ORDER_TBL.ON_CREATE,
  ORDER_TBL.ON_UPDATE,
  ORDER_TBL.ID,
  ORDER_TBL.AMOUNT,
  ORDER_TBL.TRADE_PRICE,
  ORDER_TBL.STATUS,
  customerBean.CREDIT_FACILITY AS CREDIT_FACILITY_0,
  customerBean.DISCOUNT_RATE AS DISCOUNT_RATE_0,
  customerBean.ON_CREATE AS ON_CREATE_0,
  customerBean.ON_UPDATE AS ON_UPDATE_0,
  customerBean.ID AS ID_0,
  customerBean.ADDRESS AS ADDRESS_0,
  customerBean.NAME AS NAME_0,
  itemBean.ON_CREATE AS ON_CREATE_1,
  itemBean.ON_UPDATE AS ON_UPDATE_1,
  itemBean.ID AS ID_1,
  itemBean.FULL_PRICE AS FULL_PRICE_1,
  itemBean.STOCK AS STOCK_1,
  itemBean.NAME AS NAME_1 
FROM
  ORDER_TBL 
  LEFT OUTER JOIN CUSTOMER_TBL customerBean ON ORDER_TBL.CUSTOMER_ID = customerBean.ID 
  LEFT OUTER JOIN ITEM_TBL itemBean ON ORDER_TBL.ITEM_ID = itemBean.ID 
WHERE ORDER_TBL.ID = 1
論理的なコネクションを閉じました。tx=null
物理的なコネクションを閉じました
物理的なコネクションを取得しました
論理的なコネクションを取得しました。tx=null
SELECT 
  ORDER_TBL.ON_CREATE,
  ORDER_TBL.ON_UPDATE,
  ORDER_TBL.ID,
  ORDER_TBL.AMOUNT,
  ORDER_TBL.TRADE_PRICE,
  ORDER_TBL.STATUS,
  customerBean.CREDIT_FACILITY AS CREDIT_FACILITY_0,
  customerBean.DISCOUNT_RATE AS DISCOUNT_RATE_0,
  customerBean.ON_CREATE AS ON_CREATE_0,
  customerBean.ON_UPDATE AS ON_UPDATE_0,
  customerBean.ID AS ID_0,
  customerBean.ADDRESS AS ADDRESS_0,
  customerBean.NAME AS NAME_0,
  itemBean.ON_CREATE AS ON_CREATE_1,
  itemBean.ON_UPDATE AS ON_UPDATE_1,
  itemBean.ID AS ID_1,
  itemBean.FULL_PRICE AS FULL_PRICE_1,
  itemBean.STOCK AS STOCK_1,
  itemBean.NAME AS NAME_1 
FROM
  ORDER_TBL 
  LEFT OUTER JOIN CUSTOMER_TBL customerBean ON ORDER_TBL.CUSTOMER_ID = customerBean.ID 
  LEFT OUTER JOIN ITEM_TBL itemBean ON ORDER_TBL.ITEM_ID = itemBean.ID 
WHERE ORDER_TBL.ID = 1
論理的なコネクションを閉じました。tx=null
物理的なコネクションを閉じました
物理的なコネクションを取得しました
論理的なコネクションを取得しました。tx=null
UPDATE ORDER_TBL SET 
  ON_CREATE = '2008-11-24 17.33.35',
  ON_UPDATE = '2008-11-27 01.14.33',
  AMOUNT = 5,
  TRADE_PRICE = 19,
  STATUS = '1'
WHERE
  ID = 1 AND ON_UPDATE = '2008-11-27 01.10.11'
論理的なコネクションを閉じました。tx=null
物理的なコネクションを閉じました
■■1行上書きしました
物理的なコネクションを取得しました
論理的なコネクションを取得しました。tx=null
UPDATE ORDER_TBL SET 
  ON_CREATE = '2008-11-24 17.33.35',
  ON_UPDATE = '2008-11-27 01.14.33',
  AMOUNT = 5,
  TRADE_PRICE = 19,
  STATUS = '1'
WHERE
  ID = 1 AND ON_UPDATE = '2008-11-27 01.10.11'
論理的なコネクションを閉じました。tx=null
物理的なコネクションを閉じました
org.seasar.dao.NotSingleRowUpdatedRuntimeException: [EDAO0005]更新の対象は1行(実際:0)でなければなり
ません。(com.snail.exam.s2dao.OrderBean@ae4646)
  at org.seasar.dao.impl.AbstractAutoHandler.execute(AbstractAutoHandler.java:150)
  at org.seasar.dao.impl.AbstractAutoHandler.execute(AbstractAutoHandler.java:126)
  at org.seasar.dao.impl.AbstractAutoStaticCommand.execute(AbstractAutoStaticCommand.java:53)
  at org.seasar.dao.interceptors.S2DaoInterceptor.invoke(S2DaoInterceptor.java:53)
  at org.seasar.dao.pager.PagerS2DaoInterceptorWrapper.invoke(PagerS2DaoInterceptorWrapper.java:71)
  at com.snail.exam.s2dao.OrderDao$$EnhancedByS2AOP$$da3a1e$$MethodInvocation$$update2.proceed(Met
hodInvocationClassGenerator.java)
  at com.snail.exam.s2dao.OrderDao$$EnhancedByS2AOP$$da3a1e.update(OrderDao$$EnhancedByS2AOP$$da3a1
e.java)
  at com.snail.exam.s2dao.S2DAOExam3.main(S2DAOExam3.java:35)

SELECT FOR UPDATE について

参考文献


Java#Seasar2


添付ファイル: files2dao1.png 855件 [詳細] files2dao3.png 845件 [詳細] fileoptimistic2.png 888件 [詳細] fileoptimistic1.png 800件 [詳細] files2dao2.png 823件 [詳細] fileoptimistic3.png 769件 [詳細] fileS2DaoExam.zip 890件 [詳細] fileS2DAOSample.jpg 812件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS   sitemap
Last-modified: 2008-12-19 (金) 00:58:50 (2906d)
ISBN10
ISBN13
9784061426061