java - Customize String serialization with hibernate 5 -
i'm using spring boot 1.4.2.release hibernate 5.0.11.
i have entity on have field must persist depending on field. let's entity it's this:
package com.forty2apps.entity; import javax.persistence.column; import javax.persistence.convert; import javax.persistence.entity; import javax.persistence.generatedvalue; import javax.persistence.generationtype; import javax.persistence.id; import javax.persistence.table; import java.io.serializable; import lombok.builder; @builder @entity @table(name = "max_power") public class maxpower implements serializable { @id @generatedvalue(strategy = generationtype.identity) @column(name = "id") private long id; @column(name = "problematic_field") private string problematic_field; @column(name = "charset", nullable = false) private string charset; }
i have write problematic_field byte_array bypass table encoding. first try using converter, using annotation @convert(converter = encodedutf8bytearray.class)
on problematic_field
, following class:
package com.forty2apps.entity; import javax.persistence.attributeconverter; import java.io.unsupportedencodingexception; public class encodedutf8bytearray implements attributeconverter<string, byte[]> { @override public byte[] converttodatabasecolumn(string value) { byte[] bytes; try { bytes = value.getbytes("utf-8"); } catch (unsupportedencodingexception e) { throw new runtimeexception(e); } return bytes; } @override public string converttoentityattribute(byte[] valueondb) { try { return new string(valueondb, "utf-8"); } catch (unsupportedencodingexception e) { throw new runtimeexception(e); } } }
this works, it's rigid. need create converter makes use of field charset (in best scenario... there more complex business logics may come play).
so tried defining own enhancedusertype, hoping there enough informations entity, sessionimplementor doesn't seem has helpful hoped:
package com.forty2apps.entity; import java.io.serializable; import java.io.unsupportedencodingexception; import java.sql.preparedstatement; import java.sql.resultset; import java.sql.sqlexception; import java.sql.types; import org.hibernate.hibernateexception; import org.hibernate.engine.spi.sessionimplementor; import org.hibernate.type.standardbasictypes; import org.hibernate.usertype.enhancedusertype; public class vogonstringusertype implements enhancedusertype, serializable { @override public string objecttosqlstring(object value) { return null; } @override public string toxmlstring(object value) { return null; } @override public object fromxmlstring(string xmlvalue) { return null; } @override public int[] sqltypes() { return new int[]{types.longvarbinary}; } @override public class returnedclass() { return string.class; } @override public boolean equals(object x, object y) throws hibernateexception { return false;//todo } @override public int hashcode(object x) throws hibernateexception { return x.hashcode(); } @override public object nullsafeget(resultset rs, string[] names, sessionimplementor session, object owner) throws hibernateexception, sqlexception { return "movediamo"; } @override public void nullsafeset(preparedstatement st, object value, int index, sessionimplementor session) throws hibernateexception, sqlexception { try { standardbasictypes.binary.nullsafeset(st, ((string)value).getbytes("utf-8"), index, session); } catch (unsupportedencodingexception e) { e.printstacktrace(); } } @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; } }
is there no way this? clear, want rid of hardcoded "utf-8"
string , use value in charset field; also, i'd access whole instance of entity hibernate persist/read.
thank you.
i find design questionable. rather use same encoding, always. anyway, why not use oo , encapsulation:
@embeddable public class encodedstring { @column(name = "problematic_field") private byte[] array; @column(name = "charset", nullable = false) private string charset; @transient private string value; private encodedstring() { // hibernate } public encodedstring(string value, string charset) { this.charset = charset; this.array = value == null ? null : value.getbytes(charset); this.value = value; } public string getvalue() { if (value == null && array != null) { value = new string(array, charset); } return value; } public string getcharset() { return charset; } }
Comments
Post a Comment