顯示具有 JPA 標籤的文章。 顯示所有文章
顯示具有 JPA 標籤的文章。 顯示所有文章

2014年1月20日 星期一

[JPA] @Inheritance, @DiscriminatorColumn and @DiscriminatorValue

@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


[Java] Entity, POJO and DAO

Entity
對應 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


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 後的結果

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)

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>




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 的意思


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年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
重新指定物件內屬性所對應的欄位名稱,若已是相同的欄位名稱則不需再指定。


@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")

  • 表示此物件中的 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 把值塞給物件

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 出來 塞回物件

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


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)