6

के साथ एक कार्यात्मक जावा विकल्प मैपिंग मेरे पास एक हाइबरनेट-मैप किए गए जावा ऑब्जेक्ट, JKL है, जो सामान्य हाइबरनेट-मैपेबल फ़ील्ड (जैसे तार और पूर्णांक) के समूह से भरा है। हाइबरनेट

मुझे इसमें एक नया एम्बेडेड फ़ील्ड जोड़ा गया है (जो एक ही टेबल में रहता है - मैपिंग नहीं), asdf, जो fj.data.Option<ASDF> है। मैंने इसे स्पष्ट करने के लिए एक विकल्प बना दिया है कि इस क्षेत्र में वास्तव में कुछ भी शामिल नहीं हो सकता है (जैसा कि मैं इसे एक्सेस करता हूं null को संभालने के विपरीत)।

मैं अपने JKL.hbm.xml फ़ाइल में मैपिंग कैसे स्थापित करूं? मैं ऑब्जेक्ट को पुनर्प्राप्त करते समय fj.data.Option<ASDF> के none पर null डेटाबेस में स्वचालित रूप से परिवर्तित करने के लिए हाइबरनेट करना चाहता हूं। इसे के some के fj.data.Option<ASDF> के गैर-शून्य उदाहरण को भी परिवर्तित करना चाहिए। क्या कोई और चाल है जो मुझे करना है? धन्यवाद।

उत्तर

12

मैं शुरू FunctionalJava के accessors (गेटर और सेटर) में Option सुझाव है, एक साधारण जावा क्षेत्र है जो null होने के लिए अनुमति दी है संभाल करने के लिए हाइबरनेट छोड़ने जबकि।

उदाहरण के लिए

, एक वैकल्पिक Integer क्षेत्र के लिए:

// SQL 
CREATE TABLE `JKL` (
    `JKL_ID` INTEGER PRIMARY KEY, 
    `MY_FIELD` INTEGER DEFAULT NULL 
) 

आप एक हाइबरनेट निजी क्षेत्र सीधे मैप कर सकते हैं:

// Java 
public fj.data.Option<Integer> getMyField() { 
    return fj.data.Option.fromNull(myField); 
} 

public void setMyField(fj.data.Option<Integer> value) { 
    myField = value.toNull(); 
} 
:

// Java 
@Column(nullable = true) 
private Integer myField; 

फिर आप एक्सेसर सीमा पर Option दे सकते हैं

क्या यह आपकी आवश्यकताओं के लिए काम करता है?

2

आप हाइबरनेट के कस्टम मैपिंग प्रकारों का उपयोग कर सकते हैं। दस्तावेज़ीकरण here है। यहां एक हाइबरनेट मैपिंग के लिए mapping Scala's Option का एक समान उदाहरण है।

सीधे शब्दों में कहें, आपको org.hibernate.UserType इंटरफ़ेस का विस्तार करने की आवश्यकता होगी। आप JKL -typed उप-प्रकार के साथ जेनेरिक-टाइप की गई बेस क्लास भी बना सकते हैं, जैसा कि आप स्कैला उदाहरण में देखते हैं।

0

मैं getter/setter का उपयोग कर लगता है कि सरल है, लेकिन यहाँ है कि मैं क्या यह काम करने के लिए किया था की एक उदाहरण है:

(यह संख्या और स्ट्रिंग के लिए ठीक काम करता है, लेकिन नहीं की तिथि (@Temporal टिप्पणी के साथ त्रुटि के लिए))।

import com.cestpasdur.helpers.PredicateHelper; 
import com.google.common.annotations.VisibleForTesting; 
import com.google.common.base.Optional; 
import org.apache.commons.lang.ObjectUtils; 
import org.apache.commons.lang.StringUtils; 
import org.hibernate.HibernateException; 
import org.hibernate.usertype.UserType; 
import org.joda.time.DateTime; 

import java.io.Serializable; 
import java.sql.*; 

public class OptionUserType implements UserType { 


@Override 
public int[] sqlTypes() { 
    return new int[]{ 
      Types.NULL 
    }; 
} 

@Override 
public Class returnedClass() { 
    return Optional.class; 
} 

@Override 
public boolean equals(Object o, Object o2) throws HibernateException { 
    return ObjectUtils.equals(o, o2); 

} 

@Override 
public int hashCode(Object o) throws HibernateException { 
    assert (o != null); 
    return o.hashCode(); 
} 

@Override 
public Optional<? extends Object> nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException { 
    return Optional.fromNullable(rs.getObject(names[0])); 
} 

@VisibleForTesting 
void handleDate(PreparedStatement st, Date value, int index) throws SQLException { 
    st.setDate(index, value); 
} 

@VisibleForTesting 
void handleNumber(PreparedStatement st, String stringValue, int index) throws SQLException { 
    Double doubleValue = Double.valueOf(stringValue); 
    st.setDouble(index, doubleValue); 
} 

@Override 
public void nullSafeSet(PreparedStatement st, Object value, int index) throws SQLException { 

    if (value != null) { 
     if (value instanceof Optional) { 
      Optional optionalValue = (Optional) value; 
      if (optionalValue.isPresent()) { 
       String stringValue = String.valueOf(optionalValue.get()); 


       if (StringUtils.isNotBlank(stringValue)) { 

        if (PredicateHelper.IS_DATE_PREDICATE.apply(stringValue)) { 
         handleDate(st, new Date(DateTime.parse(stringValue).getMillis()), index); 
        } else if (StringUtils.isNumeric(stringValue)) { 
         handleNumber(st, stringValue, index); 
        } else { 
         st.setString(index, optionalValue.get().toString()); 
        } 
       } else { 
        st.setString(index, null); 
       } 


      } else { 
       System.out.println("else Some"); 
      } 

     } else { 
      //TODO replace with Preconditions guava 
      throw new IllegalArgumentException(value + " is not implemented"); 

     } 
    } else { 
     st.setString(index, null); 

    } 


} 

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

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

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

@Override 
public Object assemble(Serializable serializable, Object o) throws HibernateException { 
    return serializable; 
} 

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