10 Eylül 2019 Salı

@GenericGenerator Anotasyonu

Giriş
Şu satırı dahil ederiz.
import org.hibernate.annotations.GenericGenerator;
@GeneratedValue JPA anotasyonu generator alanına değer atanarak kullanılırsa bu anotasyon işe yarar. Açıklaması şöyle
@GenericGenerator is a hibernate annotation used to denote a custom generator, which can be a class or shortcut to a generator supplied by Hibernate.
Hibernate bazı generator'leri şu isimle tanımlar
static {
    GENERATORS.put("uuid", UUIDHexGenerator.class);     // "deprecated" for new use
    GENERATORS.put("hilo", TableHiLoGenerator.class);   // removed in Hibernate 5
    GENERATORS.put("assigned", Assigned.class);
    GENERATORS.put("identity", IdentityGenerator.class);
    GENERATORS.put("select", SelectGenerator.class);
    GENERATORS.put("sequence", SequenceGenerator.class);
    GENERATORS.put("seqhilo", SequenceHiLoGenerator.class);
    GENERATORS.put("increment", IncrementGenerator.class);
    GENERATORS.put("foreign", ForeignGenerator.class);
    GENERATORS.put("guid", GUIDGenerator.class);
    GENERATORS.put("uuid.hex", UUIDHexGenerator.class); // uuid.hex is deprecated
    GENERATORS.put("sequence-identity", SequenceIdentityGenerator.class);
}
Şu generator'leri sağlar.
register("uuid2", UUIDGenerator.class);
register("enhanced-sequence", SequenceStyleGenerator.class);
register("enhanced-table", TableGenerator.class);
hilo
Örnek
Şöyle yaparız
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "hilo")
@GenericGenerator(name = "hilo",
                  strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
                  parameters = {
                    @Parameter(name = "sequence_name", value = "hilo_sequence"),
                    @Parameter(name = "initial_value", value = "1"),
                    @Parameter(name = "increment_size", value = "100"),
                    @Parameter(name = "optimizer", value = "hilo")
                }
)
private Long id;
uuid Generator - Kullanmayın 
UUIDHexGenerator Sınıfı yazısına bakabilirsiniz.

SequenceStyleGenerator
SequenceStyleGenerator yazısına bakabilirsiniz.

name Alanı
Örnek - increment
Şöyle yaparız.
@Id
@GeneratedValue(generator="increment")
@GenericGenerator(name="increment", strategy = "increment") 
Long id;
Örnek - sequence
Şöyle yaparız.
@Id
@GenericGenerator(name="honeySequence", strategy = "sequence", 
  parameters = { 
    @Parameter(name="sequence", value="HONEY_SEQ") } 
  )
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="honeySequence")
private int Id;
Örnek - uuid2
Şöyle yaparız.
@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(name = "UUID", strategy = "uuid2")
@Column(name = "id",nullable = false, updatable=false)
@Type(type="uuid-char")
private UUID id;
Örnek - oid
Şöyle yaparız.
@Id
@GenericGenerator(name = "oid", strategy = "com.foo.OurIDGenerator")
@GeneratedValue(generator = "oid")
protected Long id;
strategy Alanı
native değerini alabilir.
Örnek
Şöyle yaparız.
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator="gen")
@GenericGenerator(name = "gen", strategy = "native")
@Column(name = "id", nullable = false)
private Long id;

28 Mayıs 2019 Salı

Dirty Check

Giriş
Açıklaması şöyle. Dirty checking mekanizması Bytecode Enhancement ile iyileştirilebilir.
An entity loaded from the database is managed by Hibernate. At load time, Hibernate creates a copy of all entity property values. The state of an entity can be altered any time during runtime, and at some point, these changes are persisted back to the database.

When the time comes to flush the entities, every managed property is matched against the loading-time snapshot value. Even if only one property of a single entity has changed, Hibernate will check all of the other managed entities. The process of comparing a managed entity against its original, unmodified state is known as the dirty checking mechanism.

Hibernate executes the dirty checking mechanism during flush-time. Any change made to a managed entity is translated into an UPDATE SQL statement. The default dirty checking mechanism makes use of Java reflection and goes through each property of every managed entity.

For a small number of entities, this process might be unnoticeable; however, a large number of managed entities will definitely leave a significant CPU and memory footprint.
Örnek - After retrieving an entity
Şöyle yaparız
User user = session.get(User.class, userId);
user.setEmail("example@gmail.com");
user.setName("UpdatedName"); // "dirty checking" will be applied to this entity.
Örnek - After saving an entity
Şöyle yaparız
User newUser = new User();
session.save(newUser); newUser.setName("NewName"); // "dirty checking" will be applied to this entity.
Örnek - When transitioning from “detached” to a “persistent” state
Şöyle yaparız
session.merge(detachedUser); // "dirty checking" will be applied to this entity if it became "persistent". detachedUser.setName("AnotherName");

7 Nisan 2019 Pazar

@UpdateTimestamp Anotasyonu

Örnek
Şöyle yaparız
@Column(name = "CREATED")
@CreationTimestamp
private LocalDateTime created;

@Column(name = "LAST_UPDATED")
@UpdateTimestamp
private LocalDateTime lastUpdated;

10 Şubat 2019 Pazar

Envers @Audited Anotasyonu

Giriş
Şu satırı dahil ederiz.
import org.hibernate.envers.Audited;
Örnek
Şöyle yaparız.
@Audited
@Entity
public class MyTable {
...
}
Denetim bilgisi için iki tablo yaratırız. Şöyle yaparız. MY_TABLE_AUD id + rev bilgisini içerir.
CREATE TABLE MY_TABLE_AUD (
    ID BIGINT       NOT NULL,
    REV             INTEGER NOT NULL,
    REVTYPE         TINYINT,
   PRIMARY KEY ( id, REV )
);

create table REVINFO (
    REV  INTEGER GENERATED BY DEFAULT AS IDENTITY,
    REVTSTMP BIGINT,
    PRIMARY KEY ( REV )
);

alter table MY_TABLE_AUD
   add constraint FK5ecvi1a0ykunrriib7j28vpdj
   foreign key (REV)
   references REVINFO;
withModifiedFlag Alanı
Örnek
Elimizde şöyle bir kod olsun.
@Entity
@Audited(withModifiedFlag = true)
public class Person {
  @Id
  @GeneratedValue
  private Integer id;
  private String name;
}
Şöyle bir tablo yaratılır.
+----+------+----------+-----+---------+
| ID | name | name_MOD | REV | REVTYPE |
+----+------+----------+-----+---------+

Envers AuditReader Arayüzü

Giriş
Açıklaması şöyle.
I know that envars can store changes in db and let me extract them later with AuditReader

EmptyInterceptor Sınıfı

Giriş
Elimizde şöyle bir kod olsun
@Entity
@Audited
public class Person {
    @Id
    @GeneratedValue
    private int id;

    private String name;
    private String surname;
// add getters, setters, constructors, equals and hashCode here
}
Bu nesneyi veritabanına yazalım
Person p1 = new Person("name-1", "surname-1");
personRepository.save(p1);
Person p2 = personRepository.findOne(1L);
p2.setName("new-name");
personRepository.save(p2);
Eğer EmptyInterceptor sınıfını kullanırsak değişkliklere erişebiliriz. Açıklaması şöyle.
You could write a custom interceptor by implementing org.hibernate.EmptyInterceptor. This has callbacks to update/insert/delete with old and new snapshots of entities
onSave metodu
İmzası şöyle
public boolean onSave(Object entity,Serializable id,
    Object[] state,String[] propertyNames,Type[] types)