hibernate
I use hibernate 5.2.10, postgresql 9.6, spring data-jpa
I try to access an inet column of a postgresql database
Code:
@Converter
public class PostgresInetConverter implements AttributeConverter<Object, PGobject> {
@Override
public PGinet convertToDatabaseColumn(Object objectValue) {
if (objectValue == null) {
return null;
} else if (objectValue instanceof InetAddress) {
try {
InetAddress inet = (InetAddress) objectValue;
return new PGinet(inet.getHostAddress());
} catch (SQLException ex) {
throw new IllegalArgumentException("Unable to convert an object value", ex);
}
} else if (objectValue instanceof String) {
try {
return new PGinet((String) objectValue);
} catch (SQLException ex) {
throw new IllegalArgumentException("Unable to convert an object value", ex);
}
}
throw new IllegalArgumentException("Unable to convert object value of type "
+ objectValue.getClass().getName() + " into a "
+ PGinet.class.getName());
}
@Override
public InetAddress convertToEntityAttribute(PGobject dataValue) {
if (dataValue == null) {
return null;
} else if (dataValue instanceof PGobject) {
PGobject net = (PGobject) dataValue;
try {
String ip = net.getValue().split("/")[0];
return InetAddress.getByName(ip);
} catch (UnknownHostException ex) {
throw new IllegalArgumentException("Unable to convert an object value", ex);
}
}
throw new IllegalArgumentException("Unable to convert data value of type "
+ dataValue.getClass().getName() + " into a "
+ PGinet.class.getName());
}
}
public class PGinet extends PGobject implements Serializable, Cloneable {
private int hashValue;
/**
* This constructor takes a string in the inet format a.b.c.d[/netmask] and
* creates a new PGinet to represent it.
*
* @param s The string representation of the inet value.
* @exception SQLException If the string is invalid.
*/
public PGinet(String s)
throws SQLException {
this();
this.setValue(s);
}
/**
* A simple constructor.
*/
public PGinet() {
setType("inet");
}
/**
* This method sets the value of this PGinet object.
*
* @param v A string representation of an inet address a.b.c.d[/netmask]
* @exception SQLException If the parameter is not a valid inet address.
*/
@Override
public void setValue(String v)
throws SQLException {
if (v == null) {
throw (new PSQLException(GT.tr("Conversion to type {0} failed: {1}.",
new Object[]{type, v}), PSQLState.DATA_TYPE_MISMATCH));
}
PGtokenizer t = new PGtokenizer(v, '/');
int size = t.getSize();
if ((size != 1) && (size != 2)) {
throw (new PSQLException(GT.tr("Conversion to type {0} failed: {1}.",
new Object[]{type, v}), PSQLState.DATA_TYPE_MISMATCH));
}
int a = 0;
int b = 0;
int c = 0;
int d = 0;
int netmask = 32;
try {
if (size == 2) {
netmask = Integer.valueOf(t.getToken(1)).intValue();
if ((netmask < 0) || (netmask > 32)) {
throw (new PSQLException(
GT.tr("Conversion to typ {0} failed: {1}.", new Object[]{type, v}),
PSQLState.DATA_TYPE_MISMATCH));
}
}
t = new PGtokenizer(t.getToken(0), '.');
if (t.getSize() != 4) {
throw (new PSQLException(
GT.tr("Conversion to typ {0} failed: {1}.", new Object[]{type, v}),
PSQLState.DATA_TYPE_MISMATCH));
}
a = Integer.valueOf(t.getToken(0)).intValue();
b = Integer.valueOf(t.getToken(1)).intValue();
c = Integer.valueOf(t.getToken(2)).intValue();
d = Integer.valueOf(t.getToken(3)).intValue();
} catch (NumberFormatException e) {
throw (new PSQLException(GT.tr("Conversion to type {0} failed: {1}.",
new Object[]{type, v}), PSQLState.DATA_TYPE_MISMATCH, e));
}
// ensure that the values are within a valid range.
if ((a < 0) || (a > 255)
|| (b < 0) || (b > 255)
|| (c < 0) || (c > 255)
|| (d < 0) || (d > 255)) {
throw (new PSQLException(GT.tr("Conversion to type {0} failed: {1}.",
new Object[]{type, v}), PSQLState.DATA_TYPE_MISMATCH));
}
this.hashValue = ((a ^ c) << 24) | ((b ^ d) << 16) | ((b ^ c) << 8) | (d ^ netmask);
this.value = "" + a + "." + b + "." + c + "." + d + ((netmask == 32) ? "" : ("/" + netmask));
}
/**
* Get the hash code for this network address.
*
* @return The hash value for this object.
*/
@Override
public int hashCode() {
return (this.hashValue);
}
/**
* Compare two PGinet's for equality.
*
* @param obj The object which we wish to compare.
* @return true if it represents the same network or ip address as this
* PGinet, false otherwise.
*/
@Override
public boolean equals(Object obj) {
if (obj instanceof PGinet) {
PGinet inet = (PGinet) obj;
if (this.toString().equals(inet.toString())) {
return (true);
}
}
return (false);
}
/**
* Make a duplicate of this PGinet object.
*
* @return null on failure, or a new PGinet address which is equal to this
* object.
*/
@Override
public Object clone() {
try {
return (new PGinet(this.getValue()));
} catch (SQLException e) {
return (null);
}
}
}
@Entity
public class Test implements Serializable {
@Id
private Integer id;
@Column(columnDefinition = "inet")
@Convert(converter = PostgresInetConverter.class)
private InetAddress address;
public Test(){
}
...
}
sql table code
Code:
CREATE TABLE public.test
(
id integer,
address inet,
CONSTRAINT id PRIMARY KEY (id)
)
When i try to get a row of test i see
Quote:
select
test0_.id as id1_44_,
test0_.address as address2_44_,
test0_.initialids as initiali3_44_
from
test test0
Error i get
Quote:
org.springframework.orm.jpa.JpaSystemException: could not deserialize; nested exception is org.hibernate.type.SerializationException: could not deserialize] with root cause
java.io.StreamCorruptedException: invalid stream header: 31302E33
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:857) ~[na:1.8.0_131]