PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

PostgreSQL और SQL सर्वर के साथ UUID को हाइबरनेट करें

मेरे पास समान आवश्यकताएं थीं, लेकिन मैं भी हाइबरनेट डीडीएल पीढ़ी का उपयोग करना चाहता था और यह सुनिश्चित करना चाहता था कि SQL सर्वर ने एक अद्वितीय पहचानकर्ता प्रकार उत्पन्न किया है, और यूनिट परीक्षण के लिए hsqldb का भी समर्थन करना चाहता था। SQL सर्वर में यूयूआईडी का उपयोग करने के लिए आप निश्चित रूप से स्ट्रिंग्स के माध्यम से जाना चाहते हैं बाइनरी नहीं , क्योंकि SQL सर्वर में बाइनरी प्रतिनिधित्व एक GUID के लिए है जो UUID से अलग है। उदाहरण के लिए देखें जावा हाइबरनेट और एसक्यूएल सर्वर में यूयूआईडी का अलग प्रतिनिधित्व

आप निम्न के साथ सही मैपिंग बना सकते हैं और SQL सर्वर के लिए सही sql जेनरेट कर सकते हैं:

@Type(type = "uuid-char")
@Column(columnDefinition="uniqueidentifier")
public UUID getUuid()

और यह वैसे ही काम करता है, लेकिन दुर्भाग्य से हाइबरनेट में अलग-अलग डेटाबेस के लिए अलग-अलग कॉलमडिफिनिशन रखने का कोई तरीका नहीं है, इसलिए यह SQL सर्वर के अलावा किसी अन्य चीज़ पर विफल हो जाएगा।

इसलिए, आपको लंबा रास्ता तय करना होगा। यह सब हाइबरनेट 4.3 के लिए है:

  1. एक ओवरराइड SQLServerDialect में एक नया GUID sql प्रकार पंजीकृत करें, और आधार एक के बजाय इस बोली का उपयोग करें

    public class SQLServer2008UnicodeDialect extends SQLServer2008Dialect
    {
        public SQLServer2008UnicodeDialect() 
        {
            // the const is from the MS JDBC driver, the value is -145
            registerColumnType( microsoft.sql.Types.GUID, "uniqueidentifier" ); 

            // etc. Bonus hint: I also remap all the varchar types to nvarchar while I'm at it, like so:
            registerColumnType( Types.CLOB, "nvarchar(MAX)" );
            registerColumnType( Types.LONGVARCHAR, "nvarchar(MAX)" );
            registerColumnType( Types.LONGNVARCHAR, "nvarchar(MAX)" );
            registerColumnType( Types.VARCHAR, "nvarchar(MAX)" );
            registerColumnType( Types.VARCHAR, 8000, "nvarchar($l)" );
        }
     }
  1. एक रैपर बनाएं UUIDCustomType जो बिल्ट इन UUIDCharType के समान व्यवहार करता है लेकिन डेटाबेस प्रकार के आधार पर प्रतिनिधि। आपको init(databaseType) पहले . को कॉल करने की आवश्यकता है हाइबरनेट कॉन्फ़िगरेशन। हो सकता है कि कस्टम बोली यह कर सके, लेकिन मैं इसे अपने स्प्रिंग ऐप स्टार्टअप में कहता हूं।

डेटाबेस टाइप एक एनम था जो मेरे पास पहले से ही था जो सिस्टम कॉन्फ़िगरेशन के आधार पर सेट किया गया था, इसे बोली वर्ग या स्ट्रिंग या जो कुछ भी स्वाद के लिए संशोधित करें।

https://zorq.net/b/2012/04/21/switching-hibernates-uuid-type-mapping-per-database/

public enum DatabaseType
{
    hsqldb,
    sqlserver,
    mysql,
    postgres
}

public class UUIDCustomType extends AbstractSingleColumnStandardBasicType<UUID> implements LiteralType<UUID>
{
    private static final long serialVersionUID = 1L;

    private static SqlTypeDescriptor SQL_DESCRIPTOR;
    private static JavaTypeDescriptor<UUID> TYPE_DESCRIPTOR;

    public static void init( DatabaseType databaseType )
    {
        if ( databaseType == DatabaseType.sqlserver )
        {
            SQL_DESCRIPTOR = SqlServerUUIDTypeDescriptor.INSTANCE;
        }
        else if ( databaseType == DatabaseType.postgres  )
        {
            SQL_DESCRIPTOR = PostgresUUIDType.PostgresUUIDSqlTypeDescriptor.INSTANCE;
        }
        else
        {
            SQL_DESCRIPTOR = VarcharTypeDescriptor.INSTANCE;
        }

        TYPE_DESCRIPTOR = UUIDTypeDescriptor.INSTANCE;
    }

    public UUIDCustomType()
    {
        super( SQL_DESCRIPTOR, TYPE_DESCRIPTOR );
    }

    @Override
    public String getName()
    {
        return "uuid-custom";
    }

    @Override
    public String objectToSQLString( UUID value, Dialect dialect ) throws Exception
    {
        return StringType.INSTANCE.objectToSQLString( value.toString(), dialect );
    }

    public static class SqlServerUUIDTypeDescriptor extends VarcharTypeDescriptor
    {
        private static final long serialVersionUID = 1L;

        public static final SqlServerUUIDTypeDescriptor INSTANCE = new SqlServerUUIDTypeDescriptor();

        public SqlServerUUIDTypeDescriptor()
        {
        }

        @Override
        public int getSqlType()
        {
            return microsoft.sql.Types.GUID;
        }
    }
}
  1. कस्टम प्रकार को उस स्थान पर पंजीकृत करें जिसे हाइबरनेट उठाएगा (मेरे पास सभी संस्थाओं के लिए एक सामान्य आधार वर्ग है)। मैं इसे defaultForType =UUID.class का उपयोग करके पंजीकृत करता हूं ताकि सभी यूयूआईडी इसका उपयोग कर सकें, जिसका अर्थ है कि मुझे यूयूआईडी गुणों को एनोटेट करने की आवश्यकता नहीं है।

    @TypeDefs( {
            @TypeDef( name = "uuid-custom", typeClass = UUIDCustomType.class, defaultForType = UUID.class )
    } )
    public class BaseEntityWithId { 

चेतावनी:वास्तव में पोस्टग्रेज़ के साथ परीक्षण नहीं किया गया है, लेकिन हाइबरनेट 4.3 पर hsqldb और sql सर्वर के लिए बढ़िया काम कर रहा है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ClusterControl के साथ PostgreSQL प्रबंधन और स्वचालन

  2. रेल के साथ WHERE क्लॉज में IN के बजाय किसी का उपयोग कैसे करें?

  3. अजवाइन कार्यकर्ता डेटाबेस कनेक्शन पूलिंग

  4. PostgreSQL डेटाबेस का ऑडिट कैसे करें

  5. पीजीबैकरेस्ट कैसे स्थापित करें