2018/05/11 - [프로그램 자료/MySQL & MariaDB] - [MySQL / MariaDB] UUID GUID Key 관리방법


ANSI join 문 사용을 위해 hibernate를 5.2.x 버전으로 올리기 위해 spring boot를 2.0 버전으로 올리고 아래 내용이 동작하지 않는 다는 걸 알게 되었음

mariadb 10.x

spring 2.0

hibernate 5.2




Identify Generator(O) : 다른 세션으로 생성 후 닫기


import java.io.Serializable;

import java.sql.CallableStatement;

import java.sql.Connection;

import java.sql.SQLException;

import java.util.Properties;

 

import org.hibernate.HibernateException;

import org.hibernate.MappingException;

import org.hibernate.engine.spi.SharedSessionContractImplementor;

import org.hibernate.id.Configurable;

import org.hibernate.id.IdentifierGenerator;

import org.hibernate.service.ServiceRegistry;

import org.hibernate.type.Type;

 

import lombok.extern.slf4j.Slf4j;

 

@Slf4j

public class CustomUUIDGenerator implements IdentifierGenerator, Configurable {

   

    @Override

    public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {

        // TODO Auto-generated method stub

    }

 

    private static final String QUERY_CALL_STORE_FUNC = "{ ? = call ufn_cm_uuid_binary() }";

   

    @Override

    public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {

        // TODO Auto-generated method stub

        byte[] result = null;

        Connection connection = null;

        try {

            connection = session.getJdbcConnectionAccess().obtainConnection();

            CallableStatement callableStmt = connection.prepareCall(QUERY_CALL_STORE_FUNC);

            callableStmt.executeQuery();

            // get result from out parameter #1

            result = callableStmt.getBytes(1);

            log.debug("binary pk : {}", byteArrayToHex(result));

        } catch (SQLException sqlException) {

            throw new HibernateException(sqlException);

        }

        finally {

            try {

                if(!connection.isClosed())

                    connection.close();

            } catch (SQLException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

        }

        return result;

    }

 

    private String byteArrayToHex(byte[] a) {

        StringBuilder sb = new StringBuilder();

        for (final byte b : a)

            sb.append(String.format("%02x ", b & 0xff));

        return sb.toString();

    }

 }






Identify Generator (x)


package kr.drsoft.model.util;

 

import java.io.Serializable;

import java.util.Properties;

 

import org.hibernate.HibernateException;

import org.hibernate.MappingException;

import org.hibernate.engine.spi.SharedSessionContractImplementor;

import org.hibernate.id.Configurable;

import org.hibernate.id.IdentifierGenerator;

import org.hibernate.service.ServiceRegistry;

import org.hibernate.type.Type;

 

import lombok.extern.slf4j.Slf4j;

 

@Slf4j

public class CustomUUIDGenerator implements IdentifierGenerator, Configurable {

   

    @Override

    public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {

        // TODO Auto-generated method stub

    }

 

    private static final String QUERY_CALL_STORE_PROC = "select ufn_cm_uuid_binary()";

   

    public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {

        // TODO Auto-generated method stub

        byte[] result = null;

        try {

            result = (byte[]) session.createNativeQuery(QUERY_CALL_STORE_PROC).getSingleResult();

            log.debug("binary pk : {}", byteArrayToHex(result));

            return result;

        } catch (RuntimeException he) {

            he.printStackTrace();

            throw he;

        } 

    }

 

    private String byteArrayToHex(byte[] a) {

        StringBuilder sb = new StringBuilder();

        for (final byte b : a)

            sb.append(String.format("%02x ", b & 0xff));

        return sb.toString();

    }

}

 




Model

@Entity

@Getter

@Setter

@Table(name = "test_entity")

public class TestEntity {

        @Id

        @Column(columnDefinition = "BINARY(16)", name = "Id")

        @GenericGenerator(name = "customUuid", strategy = "com.motolies.CustomUUIDGenerator")

        @GeneratedValue(generator = "customUuid")

        private byte[] id;

 

        @Column(name = "Name", length = 50)

        private String name;

}








현재 개발환경


mariadb 10.x

spring 1.5

hibernate 5.1.x


위와 같은 환경으로 개발을 하고 있는데, PK의 기본값을 uuid로 사용하기로 했다.




숫자형 같은 경우 생성값의 전략만 정해주면 되었는데, 

uuid로 하면서 db에서 생성한 값을 가져오려고 하다보니 조금 추가해야 했다. 


Identify Generator

public class CustomUUIDGenerator extends IdentityGenerator {

        private static final String QUERY_CALL_STORE_FUNC = "{ ? = call fn_uuid_to_binary() }";

        @Override

        public Serializable generate(SessionImplementor session, Object obj) throws HibernateException {

               byte[] result = null;

               try {

                       Connection connection = session.getJdbcConnectionAccess().obtainConnection();

                       CallableStatement callableStmt = connection.prepareCall(QUERY_CALL_STORE_FUNC);

                       callableStmt.executeQuery();

                       // get result from out parameter #1

                       result = callableStmt.getBytes(1);

                } catch (SQLException sqlException) {

                       throw new HibernateException(sqlException);

               }

               return result;

         }

 }



Model

@Entity

@Getter

@Setter

@Table(name = "test_entity")

public class TestEntity {

        @Id

        @Column(columnDefinition = "BINARY(16)", name = "Id")

        @GenericGenerator(name = "customUuid", strategy = "com.motolies.CustomUUIDGenerator")

        @GeneratedValue(generator = "customUuid", strategy = GenerationType.IDENTITY)

        private byte[] id;

 

        @Column(name = "Name", length = 50)

        private String name;

}



Repository

@Repository

public interface TestEntityRepository extends JpaRepository<TestEntity, byte[]>  {

        public TestEntity findByName(String name);

}




Posted by motolies
,