ToplinkのLazy Loading その2
さっきのhttp://d.hatena.ne.jp/taedium/20060503#p1をもう少し詳しく見てみます。
DDL。CreditCard にカラム追加しました。
drop table user; drop table creditcard; drop table billingdetails; create table BillingDetails ( ID INTEGER PRIMARY KEY, DTYPE VARCHAR(31), NUMBER VARCHAR(10) ); create table CreditCard ( ID INTEGER PRIMARY KEY, EXPYEAR VARCHAR(4), EXPMONTH VARCHAR(2) ); create table User ( ID INTEGER PRIMARY KEY, BILLINGDETAILS_ID INTEGER NOT NULL, FOREIGN KEY (BILLINGDETAILS_ID) REFERENCES BILLINGDETAILS (ID) ); insert into BillingDetails values(1, 'CreditCard', '2010') insert into CreditCard values(1, '2008', '08') insert into User values(1,1)
UserクラスとBillingDetails には変更加えません。
CreditCard クラス。カラムに対応したフィールド追加しました。
@Entity public class CreditCard extends BillingDetails { private String expYear; private String expMonth; public String toString() { return "expYear=" + expYear + ", expMonth=" + expMonth; } }
実行クラス。文字を出力したり、userインスタンスのFieldやMethodを調べたりしてます
public class Client { private static EntityManagerFactory emf; private static EntityManager em; public static void main(String[] args) throws Exception { emf = Persistence.createEntityManagerFactory("emf"); createTransactionalEntityManager(); System.out.println("before em.find(User.class, 1)"); User user = em.find(User.class, 1); System.out.println("after em.find(User.class, 1)"); System.out.println("before invoking user.getBillingDetails()"); BillingDetails bd = user.getBillingDetails(); System.out.println("after invoking user.getBillingDetails()"); System.out.println("bd : " + bd); for (Class current = user.getClass(); current != null && current != Object.class; current = current.getSuperclass()) { System.out.println("detect " + current + " fields"); for (Field field : current.getDeclaredFields()) { System.out.println(current + "." + field.getName()); } System.out.println("detect " + current + " methods"); for (Method method : current.getDeclaredMethods()) { System.out.println(current + "." + method.getName()); } } closeTransactionalEntityManager(); } private static void createTransactionalEntityManager() { em = emf.createEntityManager(); em.getTransaction().begin(); } private static void closeTransactionalEntityManager() { em.getTransaction().commit(); em.close(); } }
実行結果(整形してます。SQLはログ出力されたものです。)
before em.find(User.class, 1) SELECT ID, BILLINGDETAILS_ID FROM USER WHERE (ID = ?) after em.find(User.class, 1) before invoking user.getBillingDetails() SELECT DISTINCT DTYPE FROM BILLINGDETAILS WHERE (ID = ?) SELECT t0.ID, t0.DTYPE, t0.NUMBER, t1.ID, t1.EXPYEAR, t1.EXPMONTH FROM BILLINGDETAILS t0, CREDITCARD t1 WHERE ((t0.ID = ?) AND ((t1.ID = t0.ID) AND (t0.DTYPE = ?))) after invoking user.getBillingDetails() bd : expYear=2008, expMonth=08 detect class entity.User fields class entity.User.id class entity.User.billingDetails class entity.User._toplink_billingDetails_vh detect class entity.User methods class entity.User.setId class entity.User.getBillingDetails class entity.User.setBillingDetails class entity.User.weavedValueHolders class entity.User._toplink_getbillingDetails class entity.User._toplink_setbillingDetails class entity.User._toplink_getbillingDetails_vh class entity.User._toplink_setbillingDetails_vh class entity.User.getId
なにやら怪しげな?フィールドやメソッドが追加されてました。_vhっていうサフィックスはなんでしょう。
でかけなければいけないので、とりあえずここまで。考察はid:koichikさんがしてくれるかも。