值物件?以前在 Hibernate 叫做 Component,現在 JPA 叫做 Embeddable,或者從 Annotation 的角度叫做 Element。
簡單講就是沒有 Primary Key(PK) 的資料,必須依附在有 PK 的資料下。
舉例來說,每個人(Person)有好幾種地址(Address),住家地址、公司地址、戶籍地與出生地等等,這些地址資料只對一個人有意義,脫離這個人就沒有存在的必要,或者說不能與其他人共用,既然不能共用,那就沒必要有 PK,與這個人共存亡。
2012-11-09
2012-10-30
在 Spring 3.1.2.RELEASE 使用多個資料庫的宣告式交易管理(Multiple Databases with Annotation-based Declarative Transaction Management)
一般的系統只會用到一個資料庫,Spring 引進宣告式交易管理後,設定變得很簡單。
Spring 設定檔。
然後建立 Hibernate SessionFactory,這是給 Dao 用的。
再建立 TransactionManager,這是給 Service 用的。
最後用 tx:annotation-driven 將全部串起來。
Spring 設定檔。
<context:component-scan base-package="idv.neil.model,idv.neil.service,idv.neil.dao" /> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="configLocation" value="classpath:hibernate.cfg.xml" /> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <tx:annotation-driven />先用 context:component-scan 告訴 Spring 所有的 Annotation 在哪些 package 裡。
然後建立 Hibernate SessionFactory,這是給 Dao 用的。
再建立 TransactionManager,這是給 Service 用的。
最後用 tx:annotation-driven 將全部串起來。
在 Hibernate 4.1.7.Final 使用 Annotation 的 Composite identifier
參考官方文件 5.1.2.1. Composite identifier。
有三種作法,特色 annotation 分別為 @EmbeddedId、@Id 與 @IdClass。
有三種作法,特色 annotation 分別為 @EmbeddedId、@Id 與 @IdClass。
- @EmbeddedId 是建議的作法。
- @Id 不是標準,只有 Hibernate 支援。
- @IdClass 是 EJB 年代的東西。
2011-04-19
@ManyToMany - delete inverse side object
假設兩個有著多對多關係的 class 如下:
@Entity
@SuppressWarnings("serial")
public class Author extends CommonVersionEntity {
private Set<Book> bookSet = new HashSet<Book>();
@ManyToMany
@JoinTable(name = "author_book", joinColumns = {
@JoinColumn(name = "author_id")
}, inverseJoinColumns = {
@JoinColumn(name = "book_id")
}, uniqueConstraints = @UniqueConstraint(columnNames = {
"author_id", "book_id"
}))
@ForeignKey(name = "author_book_fk", inverseName = "book_author_fk")
public Set<Book> getBookSet() {
return bookSet;
}
public void setBookSet(Set<Book> bookSet) {
this.bookSet = bookSet;
}
}
@Entity
@SuppressWarnings("serial")
public class Book extends CommonVersionEntity {
private Set<Author> authorSet = new HashSet<Author>();
@ManyToMany(mappedBy = "bookSet")
public Set<Author> getAuthorSet() {
return authorSet;
}
public void setAuthorSet(Set<Author> authorSet) {
this.authorSet = authorSet;
}
}
2007-03-22
[Note] Hibernate @Id and @AccessType
@Id
一般使用GenerationType.AUTO即可。
Hibernate存取Domain object的資料有兩種方式,一是透過getter與setter method(access by property),二是直接存取field(access by field),通常是建議使用前者,有封裝的作用。
在Hibernate Annotation中決定存取方式的規則如下:
不管是透過@AccessType設定或@Id所在位置決定,若class設定為access by property,要變更特定的attribute為access by field時,必須將@AccessType("field")放在getter method上。
不管是透過@AccessType設定或@Id所在位置決定,若class設定為access by field,要變更特定的attribute為access by property時,必須將@AccessType("property")放在field上。
最後,@Embedded與@MappedSuperclass的存取規則均同於owning/inherited entity。
一般使用GenerationType.AUTO即可。
GenerationType.AUTO - identity, sequence, or hilo
GenerationType.IDENTITY - MS SQL Server, MySQL
GenerationType.SEQUENCE - Oracle
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "...")
private Long getId() {
return id;
}
@AccessTypeHibernate存取Domain object的資料有兩種方式,一是透過getter與setter method(access by property),二是直接存取field(access by field),通常是建議使用前者,有封裝的作用。
在Hibernate Annotation中決定存取方式的規則如下:
- 若設有@AccessType,則採用@AccessType之設定。
- 不然則以@Id所在的位置決定,若@Id在property上,則採用access by property,若@Id在field上,則採用access by field。
不管是透過@AccessType設定或@Id所在位置決定,若class設定為access by property,要變更特定的attribute為access by field時,必須將@AccessType("field")放在getter method上。
不管是透過@AccessType設定或@Id所在位置決定,若class設定為access by field,要變更特定的attribute為access by property時,必須將@AccessType("property")放在field上。
最後,@Embedded與@MappedSuperclass的存取規則均同於owning/inherited entity。
2007-03-20
[Note] Hibernate Component
component要加上@Embeddable,在使用component的entity裡,可加上@Embedded或可不加,Hibernate對於沒有加上annotation的property,決定順序如下:
component可以用@Parent作成雙向關聯。
component可以用@AttributeOverride(s)來override property settings。
component還可以用@AssociationOverride(s)來override property settings。
在儲存時,若component的所有property都是null,則再次取出來時,Hibernate會認定該component為null並回傳null component,而非所有property為null的component;當然component裡若有非nullable的property就不會發生這種情況了,像是int。
component可以有component以及x-to-one的association,但是不可以有x-to-many的collection,應該是因為component沒有pk的關係吧!
可不可以把component放到獨立的table(獨立於owning entity的table)?
先說說為什麼要這樣做?因為想要將上傳檔案作成component,並將檔案內容放到db裡,再嘗試將將component作成lazy!但目前看來不可行,所以會有效能問題,最後只好將上傳檔案做成enity,改天再講這一段。
- 是不是JDK type?
- 那個class有沒有@Embeddable?
- 最後那個class有沒有Serializable?
component可以用@Parent作成雙向關聯。
component可以用@AttributeOverride(s)來override property settings。
component還可以用@AssociationOverride(s)來override property settings。
在儲存時,若component的所有property都是null,則再次取出來時,Hibernate會認定該component為null並回傳null component,而非所有property為null的component;當然component裡若有非nullable的property就不會發生這種情況了,像是int。
component可以有component以及x-to-one的association,但是不可以有x-to-many的collection,應該是因為component沒有pk的關係吧!
可不可以把component放到獨立的table(獨立於owning entity的table)?
先說說為什麼要這樣做?因為想要將上傳檔案作成component,並將檔案內容放到db裡,再嘗試將將component作成lazy!但目前看來不可行,所以會有效能問題,最後只好將上傳檔案做成enity,改天再講這一段。
訂閱:
文章 (Atom)