@Entity
@Table(name = "car")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type")
public abstract class Car { .... }
car table 中的資料可以以 type 區別為不同意義的物件
例如可以建立下列物件:
@Entity
@DiscriminatorValue("bus")
public class Bus extends Car { ... }
type = bus 的物件
@Entity
@DiscriminatorValue("truk")
public class Truk extends Car { ... }
type = truk 的物件
@DiscriminatorValue("xxxx" )
會自動存入 type = xxxx
2014年1月20日 星期一
[Java] Entity, POJO and DAO
Entity
對應 DB 的 object
POJO plain ordinary java object
不具備任何用途 用於不同地方 就是該角色
DAO data access object
訪問數據庫方法的 interface
對應 DB 的 object
POJO plain ordinary java object
不具備任何用途 用於不同地方 就是該角色
DAO data access object
訪問數據庫方法的 interface
2014年1月7日 星期二
[JPA] PersistentObjectException: detached entity passed to persist: xxx.xxx
Error Message
PersistentObjectException: detached entity passed to persist: xxx.xxx
Solution
拿掉 @OneToOne 的 cascade attribute
PersistentObjectException: detached entity passed to persist: xxx.xxx
Solution
拿掉 @OneToOne 的 cascade attribute
2013年9月3日 星期二
[JPA] Note
<tx:jta-transaction-manager>
觸發系統去找 JTA Transaction Manager
singulatAttribute
A extends B, if B 中的屬性不是基本型別 在 A 中無法識別 所以 singulatAttribute 要寫在 A 中 寫在 B 中無效
embedded object 必須宣告在 child's metamodel
namedQuery
server 開啟後便會執行 像是函數 只要有參數就能直接執行
不能做子查詢
不能使用 like
entityManager.detach(Object);
和 Object 脫鉤
construct
建立物件時 只取出其中某些欄位
criteriaQuery.select(builder.construct(
User.class,
root.get(User_.name)
))
boolean attribute
預設是 insert 0/1
加上 @Type(type = "yes_no") 則 insert Y/N
A join B
In A, if joinColumn is not primary key JPA not allowed lazy fetch.
@filterDef
filter join 後的結果
觸發系統去找 JTA Transaction Manager
singulatAttribute
A extends B, if B 中的屬性不是基本型別 在 A 中無法識別 所以 singulatAttribute 要寫在 A 中 寫在 B 中無效
embedded object 必須宣告在 child's metamodel
namedQuery
server 開啟後便會執行 像是函數 只要有參數就能直接執行
不能做子查詢
不能使用 like
entityManager.detach(Object);
和 Object 脫鉤
construct
建立物件時 只取出其中某些欄位
criteriaQuery.select(builder.construct(
User.class,
root.get(User_.name)
))
boolean attribute
預設是 insert 0/1
加上 @Type(type = "yes_no") 則 insert Y/N
A join B
In A, if joinColumn is not primary key JPA not allowed lazy fetch.
@filterDef
filter join 後的結果
2013年1月21日 星期一
[JPA] EntityNotFoundException
Error Message
javax.persistence.EntityNotFoundException: Unable to find ObjectA with id ObjectB.
Solution
join ObjectA 時,對應不到 ObjectA 時會發生該 exception。
Using @NotFound(action = NotFoundAction.IGNORE)
optional="tru|false"
表示該屬性是否允許為 null,預設為 true。
* Reference
- Annotation Type NotFound
- @Basic(fetch=FetchType,optional=true)
- @NotFound(action=NotFoundAction.IGNORE)
javax.persistence.EntityNotFoundException: Unable to find ObjectA with id ObjectB.
Solution
join ObjectA 時,對應不到 ObjectA 時會發生該 exception。
Using @NotFound(action = NotFoundAction.IGNORE)
optional="tru|false"
表示該屬性是否允許為 null,預設為 true。
* Reference
- Annotation Type NotFound
- @Basic(fetch=FetchType,optional=true)
- @NotFound(action=NotFoundAction.IGNORE)
2013年1月6日 星期日
[SQL] 分頁 performance
select * from( select x.*, rownum r from( ... )x )y where y.r >= 1 and y.r <= 10 select * from ( select row_.*, rownum rownum_ from ( ... ) row_ where rownum <= 10 ) where rownum_ > 0
寫法二會比寫法一快很多
而 JPA 的 Query setFirstResult(), setMaxResults() 生成的分頁 SQL 就會是寫法二
但 rownum <= 的值越大,查詢時間會越久
所以翻頁翻到越後面 頁面顯示的速度會越慢
[JPA] Unable to find column with logical name COLUMNNAME in table TABLENAME
Error Message
Unable to find column with logical name COLUMNNAME in table TABLENAME
Solution
若 A join B,則 B 必須被宣告在 A 之前。
<persistence-unit>
<class>B</class>
<class>A</class>
</persistence-unit>
Unable to find column with logical name COLUMNNAME in table TABLENAME
Solution
若 A join B,則 B 必須被宣告在 A 之前。
<persistence-unit>
<class>B</class>
<class>A</class>
</persistence-unit>
2012年12月1日 星期六
[JPA] transaction annotation values
TRANSACTION
- support: 依附 transaction 無則沒 transaction
- required: 裡頭行為綁在一起, 一起成功/失敗
- never: 行為分開獨立 有些成功 有些失敗
2012年10月16日 星期二
[JPA] @Embedable and @Column
C extends P
If C and P are Embedable...
得 Override getA() method
否則 A 不會 mapping 到 等於沒有寫 @Column 的意思
If C and P are Embedable...
得 Override getA() method
否則 A 不會 mapping 到 等於沒有寫 @Column 的意思
2012年8月25日 星期六
[JPA] @ModelAttribute("xxx")
// entity: request 中的值對設定到物件中。 @RequestMapping(...) public void methodName(@ModelAttribute("model") EntityType entity) {}
---- Update on 2013/08/25 ----
// @ModelAttribute("xxx") 會建立 EntityType 的物件,並且將此物件放入 request. @ModelAttribute("model") public Object prepare(...) { Object model = new EntityType(); return model; }
2012年6月15日 星期五
[JPA] @OneToMany
// ObjectA many-to-one with ObjectB // In ObjectA // mappedBy 的值是在 ObjectB 中的 attribute @OneToMany(fetch = FetchType.LAZY, mappedBy = "objectA") public List<ObjectB> getObjectB() { return objectBs; } // In ObjectB @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE }) @JoinColumns({ @JoinColumn(name = "FIELD_X", referencedColumnName = "FIELD_X", insertable = false, updatable = false ) }) public ObjectA getObjectA() { return objectA; }
2012年3月24日 星期六
2012年2月15日 星期三
@Transient, @Type
// getXXX(), isXXX(),都是對於 XXX 的操作 // 若沒有對到欄位都一定要加上 @Transient @Transient public String getAttributeA() {} @Transient public boolean isAttributeB() {} // 其實 AttributeC 在 DB 中的 type 是 string // 因此使用 @Type 來對應型別 // "yes_no" 是固定寫法,DB 會寫入 "Y" or "N" @Type(type = "yes_no") @Column(name = "STRING_ATTRIBUTE_C") public boolean isAttributeC() {}
2012年2月14日 星期二
[JPA] @Embedded, @AttributeOverride
@Embedded
此 attribute 為一個物件。
ex: 原有的 attribute A, B, C 被包裝為 Class X,那麼想使用 X 時就得加上此宣告。
@Embeddable
此物件可做為其他物件的 attribute。
@AttributeOverride
重新指定物件內屬性所對應的欄位名稱,若已是相同的欄位名稱則不需再指定。
此 attribute 為一個物件。
ex: 原有的 attribute A, B, C 被包裝為 Class X,那麼想使用 X 時就得加上此宣告。
@Embeddable
此物件可做為其他物件的 attribute。
@AttributeOverride
重新指定物件內屬性所對應的欄位名稱,若已是相同的欄位名稱則不需再指定。
@Entity(name = "ObjectX") @Table(name = "TABLE_NAME") public class ObjectX { @Embedded @AttributeOverrides({ @AttributeOverride(name = "a", column = @Column(name = "X_A")), @AttributeOverride(name = "b", column = @Column(name = "X_B")) }) public ObjectY getObjectY() { return objectY; } } @Embeddable public class ObjectY { @Column(name = "Y_A") public String getA() { return a; } @Column(name = "Y_B") public String getB() { return b; } }
2012年1月29日 星期日
[JPA] Join Objects
...query = "from SystemFunction o where o.system = :system and o.parent.id is null"..
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "PARENT_ID")
public SystemFunction getParent () { return parent; }
@JoinColumn(name = "PARENT_ID")
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "PARENT_ID")
public SystemFunction getParent () { return parent; }
@JoinColumn(name = "PARENT_ID")
- 表示此物件中的 parent 的 id 是 PARENT_ID。
- 所以 query 中的 o.parent.id 指的便是 PARENT_ID。
2011年10月15日 星期六
[JPA] Repeat fields
有重複 mapping 的欄位的話 只能有一個是可 insert 和 update 的
不然 JPA 不知道哪一個 attribute 才是要吃的值(不是取出時發生問題,是 set to db 的問題)
ex:
a attribute 跟 b attribute 都是 column "APP_ID"
存檔的時候,a 的值是 a ,b 的值是 b
它根本不知道要存 a 還是 b
[Note]
要存檔時是從物件呼叫 getter 塞給 db
setter 是從 db 取出來之後呼叫 setter 把值塞給物件
不然 JPA 不知道哪一個 attribute 才是要吃的值(不是取出時發生問題,是 set to db 的問題)
ex:
a attribute 跟 b attribute 都是 column "APP_ID"
存檔的時候,a 的值是 a ,b 的值是 b
它根本不知道要存 a 還是 b
[Note]
要存檔時是從物件呼叫 getter 塞給 db
setter 是從 db 取出來之後呼叫 setter 把值塞給物件
2011年10月9日 星期日
2011年10月1日 星期六
[JPA] Object connect to DB data
Error Message
JPA OBJECT 會和 db 連結在一起
所以修改時取出物件到頁面 當 user 更動了資料
其實 db 裡的資料也已經被更動 JPA session 裡的資料也會一同更動
因此當 user submit 後 若我們要檢查 user 是否有更動資料
再去取一次 object 是比對不出來的
因為 db 內的資料已和被更動到和頁面上的資料一樣
(在還沒 commit 前是不會更動到 db 內的資料的)
因為實際上我們取到的會是 session 裡已經被更動到的資料
(類似 browser cache)
Solution
使用 entityManager.clear() 切斷 object 和 db 間的關係 (clear session)
但切斷關係的後 使用 lazy 的 attribute 會發生取不到的問題 (因為已對應不到db)
所以在 clear 前 要先把需要用的 attribute 的 promary key 取出存下
好在要使用時能去再 select 出來 塞回物件
JPA OBJECT 會和 db 連結在一起
所以修改時取出物件到頁面 當 user 更動了資料
因此當 user submit 後 若我們要檢查 user 是否有更動資料
再去取一次 object 是比對不出來的
(在還沒 commit 前是不會更動到 db 內的資料的)
因為實際上我們取到的會是 session 裡已經被更動到的資料
(類似 browser cache)
Solution
使用 entityManager.clear() 切斷 object 和 db 間的關係 (clear session)
但切斷關係的後 使用 lazy 的 attribute 會發生取不到的問題 (因為已對應不到db)
所以在 clear 前 要先把需要用的 attribute 的 promary key 取出存下
好在要使用時能去再 select 出來 塞回物件
2011年9月23日 星期五
[JPA] javax.persistence.spi.PersistenceUnitInfo.getValidationMode()Ljavax/persistence/ValidationMode
Error Message
nested exception is java.lang.NoSuchMethodError: javax.persistence.spi.PersistenceUnitInfo.getValidationMode()Ljavax/persistence/ValidationMode;
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
Solution
weblogic /bea/setDomainEnv.sh 未指定 JPA jar path
nested exception is java.lang.NoSuchMethodError: javax.persistence.spi.PersistenceUnitInfo.getValidationMode()Ljavax/persistence/ValidationMode;
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
Solution
weblogic /bea/setDomainEnv.sh 未指定 JPA jar path
if [ "${SERVER_NAME}" = "managed01d-1" ] ; then PRE_CLASSPATH="${DOMAIN_HOME}/lib-ext/hibernate-jpa-2.0-api-1.0.0.Final.jar" export PRE_CLASSPATH fi
2011年9月18日 星期日
[JPA] unidirectional and bi-directional @OneToMany
unidirectional @OneToMany + @JoinColumn
bi-directional @OneToMany(..., mappedBy = "attributeName", orphanRemoval = true)
bi-directional @OneToMany(..., mappedBy = "attributeName", orphanRemoval = true)
訂閱:
文章 (Atom)