15 Haziran 2021 Salı

@Subselect Anotasyonu

Örnek
Açıklaması şöyle
Suppose, we have four tables (table1,table3,table4) each having a column “date”. I want to get list of max date for each table in a single query. 
The required output should be like

id  tablename max
1   table1         2020–03–25
2   table2         2020–04–30
3   table3         2020–02–28
4   table4         2020–03–31
Native SQL ile şöyle yaparız
select row_number() over() as id, * from (
  select ‘table1’ as tablename, max(date) from table1
  union
  select ‘table2’ as tablename, max(date) from table2 
  union
  select ‘table3’ as tablename, max(date) from table3
  union
  select ‘table4’ as tablename, max(date) from table4
  order by tablename
) t1;
Hibernate ile şöyle yaparız
import java.time.LocalDate;
import javax.annotation.concurrent.Immutable;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.annotations.Subselect;
import org.hibernate.annotations.Synchronize;

@Entity
@Subselect( “select row_number() over() as id, * from (" +
"select ‘table1’ as tablename, max(date) from table1 “ +
  “union " +
"select ‘table2’ as tablename, max(date) from table2 " +
"union " +
"select ‘table3’ as tablename, max(date) from table3 ” +
  “union " +
"select ‘table4’ as tablename, max(date) from table4 order by tablename) t1”)
@Synchronize({“table1”, “table2”,”table3",”table4"})
@Immutable
public class TableStatus {
 
  @Id
  private Long id;
  private String tablename;
  private LocalDate max;
  
}

@Repository
public interface TableStatusRepository extends JpaRepository<TableStatus,Long>{}
Açıklaması şöyle
Hibernate doesn’t know which database tables are used by the SQL statement configured in the @Subselect annotation. You can provide this information by annotating the entity with @Synchronize. That enables Hibernate to flush pending state transitions on tables table1, table2,table3 and table4 entities before selecting a TableStatus entity.

16 Ocak 2020 Perşembe

@Formula Anotasyonu

Giriş
Entity yüklenirken başka tablodan veri çekip yüklemek için kullanılabilir. Sınıf içindeki başka bir alana erişebilir. Açıklaması şöyle
Even if it is best to adhere to the JPA standard, in reality, many JPA providers offer additional features targeting a high-performance data access layer requirements.
For this purpose, Hibernate comes with the following non-JPA compliant features:
Örnek
Şöyle yaparız.
@Formula("(select current_date())")
Date currentDate;
Örnek
Şöyle yaparız
@Entity
@Table(name = "roles")
public class Role {

  @Id
  @GeneratedValue(generator = "roles_id_seq", strategy = GenerationType.SEQUENCE)
  @SequenceGenerator(name = "roles_id_seq", sequenceName = "roles_id_seq",
    allocationSize = 1)
  @Column(name = "id")
  private Long id;
  ...

  @Formula("(SELECT COUNT(*) FROM user_roles us WHERE us.id_role = id)")
  private Integer countUsing;
}
Örnek
Şöyle yaparız.
@MappedSuperclass
public abstract class BaseEntity {

  @Id
  protected String id;

  @Formula("(select d from SOME_TABLE ST ST.some_id = id)")
  private Long property4;

}

26 Aralık 2019 Perşembe

UserType Arayüzü

Giriş
Bir sütun veritabanından okunurken veya yazılırken çevrim için kullanılmasını istediğimiz sınıfı belirtmek için kullanılır. @Type anotasyonu ile kullanılır

Örnek
Şöyle yaparız
@Type(type = "com.vladmihalcea.book.hpjp.hibernate.type.CharacterType")
@Column(name = "event_type")
private Character type;
assemble metodu
Genellikle şöyle yaparız. Nesne Second level cache'ten okununca çağrılır..
@Override
public Object assemble(Serializable cached, Object owner) {
  return cached;
}
deepCopy metodu
Genellikle şöyle yaparız
@Override
public Object deepCopy(Object value) {
  return value;
}
disassemble metodu
Genellikle şöyle yaparız. Nesne Second level cache'te saklanmadan önce çağrılır.
@Override
public Serializable disassemble(Object o) {
  return (Serializable) o;
}
equals metodu
Genellikle şöyle yaparız. Eğer iki nesnenin referansı aynı ise Hibernate nesneyi tekrar veritabanına yazmaz.
@Override
public boolean equals(Object x, Object y) {
  return Objects.equals(x, y);
}
hashCode metodu
Genellikle şöyle yaparız.
@Override
public int hashCode(Object x) {
  return x.hashCode();
}
isMutable metodu
Genellikle şöyle yaparız. Bu kod ile veritabanından yüklenen değeri değiştirip tekrar kaydetmek istemediğimizi belirtiyoruz.
@Override
public boolean isMutable() {
  return false;
}
nullSafeGet metodu
Hibernate 5 ile imzası şöyle. Hibernate 4 ve daha eski sürümlede bu metodun imzası hep değişmiş. Hibernate 3'ten Hibernate 4'e geçerken değişmiş.
@Override
public Object nullSafeGet(ResultSet rs, String[] names,
        SharedSessionContractImplementor session, Object owner) 
throws HibernateException, SQLException ; 
Eski imzası şöyle.
@Override
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) 
throws HibernateException, SQLException ; 
Örnek
ResultSet nesnesinden okumak için şöyle yaparız. İlk sütunu okuruz, eüer string var ise ilk karakteri döneriz, yok ise null döneriz. Metodun imzası Object döndüğü için Character dönmek sorun değil.
String value = rs.getString(names[0]);
return (value != null && value.length() > 0) ? 
  value.charAt(0) : null;
Örnek
Şöyle yaparız
@Override
public Object nullSafeGet(ResultSet resultSet, String[] names,
 SessionImplementor session, Object owner)
throws HibernateException, SQLException {

  if (resultSet.getArray(names[0]) == null) {
    return new String[0];
  }

  Array array = resultSet.getArray(names[0]);
  @SuppressWarnings("unchecked")
  T javaArray = (T) array.getArray();
  return javaArray;
}
nullSafeSet metodu
Hibernate 5 ile imzası şöyle. Hibernate 4 ve daha eski sürümlede bu metodun imzası hep değişmiş. Hibernate 3'ten Hibernate 4'e geçerken değişmiş.
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index,
        SharedSessionContractImplementor session) 
throws HibernateException, SQLException;
Eski imzası şöyle.
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index) 
throws HibernateException, SQLException;
Örnek
PrepararedStatement'a yazmak için şöyle yaparız.
if (value == null) {
  st.setNull(index, Types.CHAR);
} else {
  st.setString(index, String.valueOf(value));
}
replace metodu
Detached nesneyi merge etmek için çağrılır.
Örnek
Genellikle şöyle yaparız.
@Override
public Object replace(Object o, Object target, Object owner) {
  return o;
}
Örnek
Şöyle yaparız.
@Override
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
  return original;
}
returnedClass metodu
İmzası şöyle. Bu sınıfın okuyup yazdığı kendi kodumuzdaki sınıf tipini belirtir. @Type ile verilen ilk örnekte bizim kodumuz Character nesnesidir. Foo da olabilirdi.
@Override
public Class returnedClass();
Örnek
Şöyle yaparız.
public class GenericStringArrayUserType<T extends Serializable> implements UserType {

  private Class<T> typeParameterClass;

  @Override
  public Class<T> returnedClass() {
    return typeParameterClass;
  }
}

sqlTypes metodu
char sütun tipi için şöyle yaparız.
@Override
public int[] sqlTypes() { 
  return new int[]{Types.CHAR}; 
}