22 Ekim 2018 Pazartesi

JPA @Table Anotasyonu

Giriş
Şu satırı dahil ederiz.
import javax.persistence.Table;
catalog Alanı
Şöyle yaparız. Catalog ve Schema arasındaki farkı anlamadım.
@Entity
@Table(name = "my", catalog = "dev_db")
public class MyEntity {
  ...
}
name Alanı
Eğer tablo ismi belirtilmemişse sınıf ismi (unqualified class name) tablo ismi olarak kullanılır.

Örnek
Şöyle yaparız.
@Entity
@Table(name = "ROOM")
public class Room {..}
Örnek
Şöyle yaparız.
@Entity
@Table(name = "fee_terms", catalog = "campus_guru_01")
public class FeeTerms implements java.io.Serializable {
  ...
}
schema Alanı
Eğer istenirse schema da belirtilebilir.
@Entity
@Table(name="NODE_TYPE", schema="SCHEMA_DATA")
public class NodeType {...}
uniqueConstraints  alanı
Şöyle yaparız.
@Table(uniqueConstraints = [UniqueConstraint(columnNames = arrayOf("isbn"))])

FutureTask Sınıfı - Callable Nesneyi Runnable Nesneye Adapte Eder

Giriş
Açıklması şöyle
... as the parameter for the Thread constructor needs to implement Runnable interface, which is not implemented by Callable. Hence, in order to solve this, we can use FutureTask. FutureTask is an implementation class which implements RunnableFuture interface, which extends Runnable interface.
Yani bu sınıf hem Future hem de Runnable arayüzlerinden kalıtır. Böylece FutureTask ExecutorService.execute() veya Thread(...).start() şeklinde kullanılabilir ve de bir sonuç dönebilir.

Kalıtım şöyle
Runnable
Future
  RunnableFuture
    FutureTask

Callable Kullanımı
Örnek - Thread
Şöyle yaparız
Callable<JSONObject> userCall = new Callable<JSONObject>() {
  @Override
  public JSONObject call() throws Exception {
    //Use userName API
    String name = remoteService.getUserName(userId);
    ...;
  }
};

FutureTask<JSONObject> userFuture = new FutureTask<>(userCall);

new Thread(userFuture).start();

try {
  userFuture.get());
} catch (InterruptedException | ExecutionException e) {
  ...
}
Örnek - ExecutorService
Şöyle yaparız.
FutureTask<String> futureTask = new FutureTask<String>(new Callable<String>() {
  public String call() throws Exception {
    return ...;
  }
});
executor.execute(futureTask);
...
String value = futureTask.get();
Runnable Kullanımı
Örnek - Thread
Şöyle yaparız. Burada Runnable bitince null değeri döndürülür
Runnable task = ...
FutureTask<Runnable> futureTask = new FutureTask<>(task, null);
new Thread(futureTask).start();
return futureTask.get;


21 Ekim 2018 Pazar

Holder Singleton

Giriş
Lazy singleton olaran adlandırabiliriz. Açıklaması şöyle.
The implementation of the idiom relies on the initialization phase of execution within the Java Virtual Machine (JVM) as specified by the Java Language Specification (JLS).[3] When the class Something is loaded by the JVM, the class goes through initialization. Since the class does not have any static variables to initialize, the initialization completes trivially. The static class definition LazyHolder within it is not initialized until the JVM determines that LazyHolder must be executed. The static class LazyHolder is only executed when the static method getInstance is invoked on the class Something, and the first time this happens the JVM will load and initialize the LazyHolder class. The initialization of the LazyHolder class results in static variable INSTANCE being initialized by executing the (private) constructor for the outer class Something. Since the class initialization phase is guaranteed by the JLS to be sequential, i.e., non-concurrent, no further synchronization is required in the static getInstance method during loading and initialization. And since the initialization phase writes the static variable INSTANCE in a sequential operation, all subsequent concurrent invocations of the getInstance will return the same correctly initialized INSTANCE without incurring any additional synchronization overhead.

While the implementation is an efficient thread-safe "singleton" cache without synchronization overhead, and better performing than uncontended synchronization,[4] the idiom can only be used when the construction of Something can be guaranteed to not fail. In most JVM implementations, if construction of Something fails, subsequent attempts to initialize it from the same class-loader will result in a NoClassDefFoundError failure.
Holder sınıfı private static olur ve içinde kendi sınıfımın public static bir alanını içerir.

Holder içinde Holder ilklendirildiği tuhaf durumlar da gördüm.

Örnek
Şöyle yaparız.
public static class Singleton {
  private static class InstanceHolder {
    public static Singleton instance = new Singleton();
  }

  private Singleton(){}

  public static Singleton getInstance() { 
    return InstanceHolder.instance;
  }
}
Örnek
Şöyle yaparız. Yine static alan kullanılıyor tek farkı içte ayrı bir sınıf kullanılması
public class Singleton  {    
  private static class SingletonHolder {    
    public static final Singleton instance = new Singleton();
  }    

  public static Singleton getInstance() {    
    return SingletonHolder.instance;    
  }

  private Singleton() {
    //...
  }
}

18 Ekim 2018 Perşembe

JPA @Id Anotasyonu

Giriş
Şu satırı dahil ederiz.
import javax.persistence.Id;
Her @Entity ile işaretli sınıfın @Id anotasyonuna yani primary key alanına sahip olması gerekir. Eğer bu anotasyon yoksa şu exception fırlatılır.
No identifier specified for entity: com.foo.bar
Composite primary key için bu anotasyon yerine @IdClass kullanılır. Hibernate birden fazla @Id anotasyonuna izin veriyor ancak bu kullanım JPA uyumlu değil. Açıklaması şöyle.
Another, arguably more natural, approach is to place @Id on multiple properties of your entity. This approach is only supported by Hibernate (not JPA compliant) but does not require an extra embeddable component.
Örnek
Eğer @Id için GeneratedValue kullanmak istemezsek şöyle yaparız. Bu durumda primary key değerlerini kendimiz yönetiriz.
@Id
@Column(unique=true)
private int id;


17 Ekim 2018 Çarşamba

JPA @JoinColumn Anotasyonu

Giriş
Şu satırı dahil ederiz.
import javax.persistence.JoinColumn;
Açıklaması şöyle.
The attributes in @JoinColumn are the names of the database table column.
Açıklaması şöyle.
The join column is declared with the @JoinColumn annotation which looks like the @Column annotation. It has one more parameters named referencedColumnName. This parameter declares the column in the targeted entity that will be used to the join. Note that when using referencedColumnName to a non primary key column, the associated class has to be Serializable. Also note that the referencedColumnName to a non primary key column has to be mapped to a property having a single column (other cases might not work).
ManyToOne, OneToMany, OneToOne anotasyonları ile birlikte kullanılır.

Normalde bidirectional (çift yönlü) OneToMany ilişkide A tablosu, B tablosu ve A_B join tablosu üretilir. Bu durumda @JoinColumn anotasyonu name + joinColumns + inverseJoinColumns alanları doldurularak kullanılır.

Eğer unidirectional (tek yönlü) OneToMany ilişki istiyorsak yani A tablosu, B tablosu yaratılır ve B tablosuna A_ID şeklinde parent için foreign key yerleştirilir. Bu durumda @JoinColumn anotasyonu sadece name + joinColumns alanları doldurularak kullanılır. Açıklaması burada.

name Alanı
Sütun ismini belirtir.

Örnek
Unidirectional OneToMany ilişkide child tablodaki parent tabloya foreign key olan sütun ismi yazılır. Şöyle yaparız.
@OneToMany
@JoinColumn(name="A_ID")
private List<C> cList;
Örnek
ManyToOne ilişkide child sınıfta şöyle yaparız. Child tablodaki parent tabloya foreign key olan sütun ismi yazılır.
@ManyToOne
@JoinColumn(name="parent_fk")
private DomainObject domainObject;
Örnek
ManyToOne ilişkide child sınıfta şöyle yaparız. Child tablodaki parent tabloya foreign key olan sütun ismi yazılır.
class customer {

  @Id
  private Long id;
  private String name;
  private Company company;
}

class Company {

  @Id
  private Long id;
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "ownedBy")
  private Company ownedBy;
}
Örnek - Sütün İsmi Yoksa
Eğer sütun ismi tanımlanmazsa şu isim kullanılır.
<field_name>_<id_column_name>
Yani aşağaki örnekte Address sınıfı için "field_name" address "id_column_name" ise id kabul edilir ve sütun ismi address_id olur.
@ManyToOne
@JoinColumn
public Address getAddress() { 
    return address; 
}
referenceColumnName Alanı
Örnek
ManyToOne ilişkide child sınıfta parent tablodaki sütunu belirtmek için şöyle yaparız
@JoinColumn(name="domain_object_id",referenceColumnName="domain_id")