顯示具有 Hibernate Annotation 標籤的文章。 顯示所有文章
顯示具有 Hibernate Annotation 標籤的文章。 顯示所有文章

2012-11-09

在 Spring MVC 3.1.2.RELEASE 與 Hibernate 4.1.7.Final 實作變動數量的值物件(Variable Component)

值物件?以前在 Hibernate 叫做 Component,現在 JPA 叫做 Embeddable,或者從 Annotation 的角度叫做 Element。

簡單講就是沒有 Primary Key(PK) 的資料,必須依附在有 PK 的資料下。

舉例來說,每個人(Person)有好幾種地址(Address),住家地址、公司地址、戶籍地與出生地等等,這些地址資料只對一個人有意義,脫離這個人就沒有存在的必要,或者說不能與其他人共用,既然不能共用,那就沒必要有 PK,與這個人共存亡。

2012-10-30

在 Spring 3.1.2.RELEASE 使用多個資料庫的宣告式交易管理(Multiple Databases with Annotation-based Declarative Transaction Management)

一般的系統只會用到一個資料庫,Spring 引進宣告式交易管理後,設定變得很簡單。

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。
  • @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即可。
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;
}
@AccessType

Hibernate存取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可放在class、field或property上,在class上表示設定為class level,整個class套用,在field或property上則為attribute level,僅該attribute(property或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,決定順序如下:
  1. 是不是JDK type?
  2. 那個class有沒有@Embeddable?
  3. 最後那個class有沒有Serializable?
如果不想讓property成為persistence,可以加上@Transient或transient。

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,改天再講這一段。