2009-12-22 9 views
8

पोस्टग्रेएसक्यूएल के तहत, मैं एसक्यूएल प्रकार अंतराल & अवधि के बीच मैपिंग के लिए PersistentDuration का उपयोग कर रहा हूं लेकिन यह काम नहीं करता है।हाइबरनेट में अंतराल के प्रकार को कैसे मैप करें?

अन्य उपयोगकर्ता एक ही मुद्दा & अपने ही वर्ग के साथ आ पाया:

public void nullSafeSet(PreparedStatement statement, Object value, int index) 
     throws HibernateException, SQLException { 
    if (value == null) { 
     statement.setNull(index, Types.OTHER); 
    } else { 
     Long interval = ((Long) value).longValue(); 
     Long hours = interval/3600; 
     Long minutes = (interval - (hours * 3600))/60; 
     Long secondes = interval - (hours * 3600) - minutes * 60; 
      statement.setString(index, "'"+ hours +":" 
        + intervalFormat.format(minutes) + ":" 
        + intervalFormat.format(secondes)+"'"); 

    } 
} 

लेकिन यह वास्तविक स्वरूप के साथ काम नहीं करता है, क्योंकि यह लगता है अंतराल पैटर्न केवल "hh: mm: ss" है । देख

यहाँ कुछ कुछ वास्तविक उदाहरण मैं डेटाबेस से पार्स करने के लिए की जरूरत है::

 
1 day 00:29:42 
00:29:42 
1 week 00:29:42 
1 week 2 days 00:29:42 
1 month 1 week 2 days 00:29:42 
1 year 00:29:42 
1 decade 00:29:42 

http://www.postgresql.org/docs/current/interactive/datatype-datetime.html

आप एक साफ समाधान है कि ऐसा नहीं है?

उत्तर

0

लिंक के मुताबिक आपके पास दिन के बाद एक दिन होना चाहिए: मिनट: सेकंड। तो कोड को कुछ निम्नलिखित मानते हुए मानते हुए कि आपको कभी अंतराल में 23 घंटे 59 मिनट अधिक होने की आवश्यकता नहीं है।

statement.setString(index, "'0 "+ hours +":" 
+ intervalFormat.format(minutes) + ":" 
+ intervalFormat.format(secondes)+"'"); 

मैं इस कोड का परीक्षण करने में सक्षम नहीं हूं क्योंकि मेरे पास PostGreSql इंस्टॉल नहीं है। इस मुद्दे पर एक और चर्चा के लिए निम्न लिंक देखें, हालांकि आपको सेकंड को संभालने के लिए प्रदान किए गए कोड को संशोधित करना होगा। हालांकि यह एक समस्या का ज्यादा नहीं होना चाहिए।

https://forum.hibernate.org/viewtopic.php?p=2348558&sid=95488ce561e7efec8a2950f76ae4741c

+0

नहीं यह एक दिन.और वहाँ न केवल keywork दिन (वर्ष, माह, सप्ताह, .. लिंक ऊपर देखें) यहाँ डेटाबेस से कुछ वास्तविक उदाहरण के लिए अनिवार्य है: 2 9: 42 -00: 2 9: 42 -1 सप्ताह 00:29:42 1 सप्ताह 2 दिन 00:29:42 1 महीने 1 सप्ताह 2 दिन 00:29:42 -1 वर्ष 00:29:42 1 दशक 00:29:42 – adam

3

यह जेपीए, हाइबरनेट (एनोटेशन के साथ) के लिए एक काम समाधान है।

इस इकाई कक्षा की शुरुआत है (टेबल अंतराल स्तंभ है कि के लिए):

@Entity 
@Table(name="table_with_interval_col") 
@TypeDef(name="interval", typeClass = Interval.class) 
public class TableWithIntervalCol implements Serializable { 

यह अंतराल स्तंभ है:

@Column(name = "interval_col", nullable = false) 
@Type(type = "interval")  
private Integer intervalCol; 

और यह अंतराल वर्ग है:

package foo.bar.hibernate.type; 

import java.io.Serializable; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Types; 
import java.util.Date; 

import org.hibernate.HibernateException; 
import org.hibernate.usertype.UserType; 
import org.postgresql.util.PGInterval; 


/** 
* Postgres Interval type 
* 
* @author bpgergo 
* 
*/ 
public class Interval implements UserType { 
    private static final int[] SQL_TYPES = { Types.OTHER }; 

    @Override 
    public int[] sqlTypes() { 
     return SQL_TYPES; 
    } 

    @SuppressWarnings("rawtypes") 
    @Override 
    public Class returnedClass() { 
     return Integer.class; 
    } 

    @Override 
    public boolean equals(Object x, Object y) throws HibernateException { 
     return x.equals(y); 
    } 

    @Override 
    public int hashCode(Object x) throws HibernateException { 
     return x.hashCode(); 
    } 

    @Override 
    public Object nullSafeGet(ResultSet rs, String[] names, Object owner) 
      throws HibernateException, SQLException { 
     String interval = rs.getString(names[0]); 
     if (rs.wasNull() || interval == null) { 
      return null; 
     } 
     PGInterval pgInterval = new PGInterval(interval); 
     Date epoch = new Date(0l); 
     pgInterval.add(epoch); 
     return Integer.valueOf((int)epoch.getTime()/1000); 
    } 

    public static String getInterval(int value){ 
     return new PGInterval(0, 0, 0, 0, 0, value).getValue(); 
    } 


    @Override 
    public void nullSafeSet(PreparedStatement st, Object value, int index) 
      throws HibernateException, SQLException { 
     if (value == null) { 
      st.setNull(index, Types.VARCHAR); 
     } else { 
      //this http://postgresql.1045698.n5.nabble.com/Inserting-Information-in-PostgreSQL-interval-td2175203.html#a2175205 
      st.setObject(index, getInterval(((Integer) value).intValue()), Types.OTHER); 
     } 
    } 

    @Override 
    public Object deepCopy(Object value) throws HibernateException { 
     return value; 
    } 

    @Override 
    public boolean isMutable() { 
     return false; 
    } 

    @Override 
    public Serializable disassemble(Object value) throws HibernateException { 
     return (Serializable) value; 
    } 

    @Override 
    public Object assemble(Serializable cached, Object owner) 
      throws HibernateException { 
     return cached; 
    } 

    @Override 
    public Object replace(Object original, Object target, Object owner) 
      throws HibernateException { 
     return original; 
    } 

} 
0

PostgreSQL में date_part/निकालने का फ़ंक्शन है जिसका उपयोग आप अलग-अलग लौटने के लिए कर सकते हैं खेतों, युग उनमें से एक है। अंतराल से युग निकालने पर, आपको अंतराल में निहित सेकंड की संख्या प्राप्त होती है, और वहां से आप कन्वर्ट कर सकते हैं हालांकि आप चाहें। मैंने हाइबरनेट के साथ अपना अनुभव खो दिया, लेकिन आप इसे इस तरह से कर सकते हैं:

SELECT 
    average_interval_between_airings 
    , date_part('epoch', average_interval_between_airings)/60 as minutes 
    , date_part('epoch', average_interval_between_airings) as seconds 
FROM shows; 
1

क्यों न केवल इसे एक संख्यात्मक और नक्शे में बदल दें? -1 दिन 00:

SELECT EXTRACT(epoch FROM my_interval) 
संबंधित मुद्दे