21 Temmuz 2023 Cuma

JDBC Enum String İçin Posgtre'ye Özel Çözümler

Örnek
Elimizde şöyle bir PostgreSQL tablosu olsun. Burada order_status isimli yeni bir type yarattık.
CREATE TYPE order_status AS ENUM(
  'Ordered', 
  'Baking', 
  'Delivering', 
  'YummyInMyTummy');

CREATE TABLE pizza_order (
  id INT PRIMARY KEY,
  status order_status NOT NULL,
  order_time TIMESTAMP NOT NULL DEFAULT now()
);
Bu type aslında Java kodu olarak şöyle
public enum OrderStatus {
  Ordered,
  Baking,
  Delivering,
  YummyInMyTummy
}
Şu SQL çalışır, çünkü status tipi olarak CREATE TYPE ile belirtilen bir string verdik
INSERT INTO pizza_order (id, status, order_time) 
VALUES (1, 'Ordered', now());
Ama JDBC olarak çalışmaz
PreparedStatement statement = conn
  .prepareStatement("INSERT INTO pizza_order (id, status, order_time) VALUES(?,?,?)");

statement.setInt(1, 1);
statement.setString(2, OrderStatus.Ordered.toString());
statement.setTimestamp(3, Timestamp.from(Instant.now()));

statement.executeUpdate();
Hata şöyle. Yani veri tabanı varchar'ı status type'a nasıl çevireceğini bilmiyor.
org.postgresql.util.PSQLException: ERROR: column "status" is of type order_status but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
Çözüm 1
java.sql.Types.OTHER kullanırız.
PreparedStatement statement = conn
  .prepareStatement("INSERT INTO pizza_order (id, status, order_time) VALUES(?,?,?)");

statement.setInt(1, 1);
statement.setObject(2, OrderStatus.Ordered, java.sql.Types.OTHER);
statement.setTimestamp(3, Timestamp.from(Instant.now()));

statement.executeUpdate();
Çözüm 2
String olarak geçebilmek için CAST yaratılır. 
CREATE CAST (varchar AS order_status) WITH INOUT AS IMPLICIT;
O zaman hem JDBC ile enum'u string olarak yazabiliriz, hem de String'i Java Enum olarak okuyabiliriz. Yazma için şöyle yaparız
PreparedStatement statement = conn
  .prepareStatement("INSERT INTO pizza_order (id, status, order_time) VALUES(?,?,?)");

statement.setInt(1, 1);
statement.setString(2, OrderStatus.Ordered.toString());
statement.setTimestamp(3, Timestamp.from(Instant.now()));

statement.executeUpdate();
Okuma için şöyle yaparız
PreparedStatement statement = conn.prepareStatement("SELECT id, status, order_time " +
	"FROM pizza_order WHERE id = ?");
statement.setInt(1, 1);

ResultSet resultSet = statement.executeQuery();
resultSet.next();

PizzaOrder order = new PizzaOrder();

order.setId(resultSet.getInt(1));
order.setStatus(OrderStatus.valueOf(resultSet.getString(2)));
order.setOrderTime(resultSet.getTimestamp(3));

Hiç yorum yok:

Yorum Gönder

Bean Validation @GroupSequence Anotasyonu

Örnek Elimizde şöyle bir kod olsun public class SampleRequest {   @NotNull   LocalDate startDate;   @NotNull   LocalDate endDate;   @AssertT...