====== Hibernate Annotations ====== * 하이버네이트 전용 어노테이션들 * [[https://dzone.com/articles/all-hibernate-annotations-mapping-annotations|All Hibernate Annotations: Mapping Annotations - DZone Java]] ===== CRUD 쿼리 직접 지정 ===== * [[https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Web_Platform/5/html/Hibernate_Annotations_Reference_Guide/entity-hibspec-customsql.html|3.4.11. Custom SQL for CRUD operations]] @Entity @Table(name="CHAOS") @SQLInsert( sql="INSERT INTO CHAOS(size, name, nickname, id) VALUES(?,upper(?),?,?)") @SQLUpdate( sql="UPDATE CHAOS SET size = ?, name = upper(?), nickname = ? WHERE id = ?") @SQLDelete( sql="DELETE CHAOS WHERE id = ?") @SQLDeleteAll( sql="DELETE CHAOS") @Loader(namedQuery = "chaos") @NamedNativeQuery(name="chaos", query="select id, size, name, lower( nickname ) as nickname from CHAOS where id= ?", resultClass = Chaos.class) public class Chaos { @Id private Long id; private Long size; private String name; private String nickname; * ''@Loader'': * Entity 단건 SELECT 에 대한 쿼리를 HQL, Native Query로 지정할 수 있다. * namedQuery로 만들어 놓고, 그 nameQuery 이름을 지정해준다. * ''@SQLInsert'',, ''@SQLUpdate'', ''@SQLDelete'', ''@SQLDeleteAll'' * SQL 파라미터의 순서가 매우 중요하다. 위 어노테이션들을 지정하기 전에 먼저 ''org.hibernate.persister.entity'' Log Level을 ''DEBUG''로 지정하고 보면 하이버네이트가 생성한 SQL과 파라미터 순서를 볼 수 있는데, 이와 똑 같은 순서로 SQL 파라미터를 지정해야 한다. * Secondary Table에 대한 지정 @Entity @SecondaryTables({ @SecondaryTable(name = "`Cat nbr1`"), @SecondaryTable(name = "Cat2"}) @org.hibernate.annotations.Tables( { @Table(appliesTo = "Cat", comment = "My cat table" ), @Table(appliesTo = "Cat2", foreignKey = @ForeignKey(name="FK_CAT2_CAT"), fetch = FetchMode.SELECT, sqlInsert=@SQLInsert(sql="insert into Cat2(storyPart2, id) values(upper(?), ?)") ) } ) public class Cat implements Serializable { * Join Column에 대한 지정 @OneToMany @JoinColumn(name="chaos_fk") @SQLInsert( sql="UPDATE CASIMIR_PARTICULE SET chaos_fk = ? where id = ?") @SQLDelete( sql="UPDATE CASIMIR_PARTICULE SET chaos_fk = null where id = ?") private Set particles = new HashSet(); ===== @org.hibernate.annotations.ForeignKey ===== * Deprecated. **JPA 2.1** 에서 부터 ''@JoinColumn(foreinKey=@ForeinKey...)'' 표준이 생겨서 더이상 이 애노테이션은 불필요하다. * ''@org.hibernate.annotations.ForeignKey(name="fk_parent_id_child")'' : 객체간의 연관을 맺을 때 FK 인덱스의 이름을 명시해준다. * 이를 명시하지 않으면 ''FK숫자여러개지정''으로 된다. * ''@org.hibernate.annotations.ForeignKey(name="none")'' : **name="none"**은 FK를 강제로 못 맺게 한다. [[https://forum.hibernate.org/viewtopic.php?f=6&t=978321|Forcing hbm2ddl to not generate an FK]] ===== @org.hibernate.annotations.ColumnTransformer ===== * [[https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/annotations/ColumnTransformer.html|ColumnTransformer]] * 컬럼에서 데이터를 저장하거나 읽기 전에 변환 과정을 거칠 수 있다. * [[https://www.programcreek.com/java-api-examples/index.php?api=org.hibernate.annotations.ColumnTransformer|Java Code Examples org.hibernate.annotations.ColumnTransformer]] * [[https://www.thoughts-on-java.org/map-encrypted-database-columns-hibernates-columntransformer-annotation/|How to map encrypted database columns with Hibernate]] * Field에 지정할 때는 ''@ColumnTransformer'', Class에 지정할 때는 ''@ColumnTransformers''로 다중지정 가능. @Column @ColumnTransformer(read = “pgp_sym_decrypt(creditCardNumber, ‘mySecretKey’)”, write = “pgp_sym_encrypt(?, ‘mySecretKey’)”) private String creditCardNumber; ===== @org.hibernate.annotations.DynamicInsert ===== * [[https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/annotations/DynamicInsert.html|@org.hibernate.annotations.DynamicInsert]] * ''insert'' 구문 생성시 null 값에 대해서는 생성하지 않는다. * [[http://www.mkyong.com/hibernate/hibernate-dynamic-insert-attribute-example/|Hibernate – dynamic-insert attribute example]] ===== @org.hibernate.annotations.DynamicUpdate ===== * [[https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/annotations/DynamicUpdate.html|@org.hibernate.annotations.DynamicUpdate]] * ''update'' 구문 생성시 변경된 것에 대해서만 생성한다. * [[http://www.mkyong.com/hibernate/hibernate-dynamic-update-attribute-example/|Hibernate – dynamic-update attribute example]] * [[https://thorben-janssen.com/dynamic-inserts-and-updates-with-spring-data-jpa/|Dynamic Inserts and Updates with Spring Data JPA]] ===== @org.hibernate.annotations.Immutable ===== * [[https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/annotations/Immutable.html|@org.hibernate.annotations.Immutable]] * [[https://vladmihalcea.com/immutable-entity-jpa-hibernate/|How to map an immutable entity with JPA and Hibernate - Vlad Mihalcea]] * Entity나 immutable로 지정하면 수정이 작동하지 않게 된다. * Collection을 immutable로 지정하면 추가나 삭제가 작동하지 않게 된다. * **''@Immutable''에 update를 날리면 오류 없이 그냥 무시**하고 넘어간다. 오류가 발생하게 하려면 설정이 필요하다. * 주의! : ''@Immutable'' 엔티티는 여전히 JPQL이나 Criteria로 업데이트 가능하다. 단, **5.2.17**부터는 업데이트를 막았으나 WARNING만 남긴다. 여기에 오류까지 발생시키려면 아래 프라퍼티를 설정한다. hibernate.query.immutable_entity_update_query_handling_mode=exception * [[https://github.com/hibernate/hibernate-orm/pull/2216|HHH-12387 - Immutable entities can be updated via bulk update queries by vladmihalcea · Pull Request #2216 · hibernate/hibernate-orm]] ===== @org.hibernate.annotations.OptimisticLocking ===== * [[https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/annotations/OptimisticLocking.html|@org.hibernate.annotations.OptimisticLocking]] * 낙관적 잠금의 방식을 지정한다. * [[https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/annotations/OptimisticLockType.html|OptimisticLockType]] ===== @org.hibernate.annotations.Persister ===== * [[https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/annotations/Persister.html|@org.hibernate.annotations.Persister]] ===== @org.hibernate.annotations.Polymorphism ===== * [[https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/annotations/Polymorphism.html|Polymorphism]] * [[https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/annotations/PolymorphismType.html|PolymorphismType]] 지정. ===== @org.hibernate.annotations.SelectBeforeUpdate ===== *[[https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/annotations/SelectBeforeUpdate.html|SelectBeforeUpdate]]