Alexey, I like this very much, this almost solve my problems and I do not need any fabrics!
Thanks! On Thu, Oct 29, 2015 at 9:19 PM, Alexey Goncharuk < alexey.goncha...@gmail.com> wrote: > Alexey, > > What if we create a thin wrapper around PortableBuilder that implements > IgniteObject? Since PortableBuilder already has getField() method, you only > need to delegate to a builder in this wrapper. Then we can invoke the > interface Dmitriy suggested, obtain hashCode and set it back to the > builder. > > In pseudo-code: > > PortableBuilder bld = getBuilder(); > > populateFromResultSet(bld); > > IgniteObject bldView = new BuilderIgniteObjectView(bld); > > int hashCode = hashBuilder.hashCode(bldView); > bld.hashCode(hashCode); > > bld.build(); > > > Thoughts? > > 2015-10-29 16:34 GMT+03:00 Alexey Kuznetsov <akuznet...@gridgain.com>: > > > Dmitriy, > > > > > How about adding JdbcTypeHasher interface, which will look like this: > > > interface JdbcTypeHasher { > > > public int hashCode(IgniteObject o, Collection<String> fields); > > >} > > > User should be optionally set this interface at the JdbcType level. If > > not > > > set, then we use our default implementation. > > > Will this work? > > > > First I thought it will work, but when I started to implement hasher > > support I faced several problems: > > 1) IgniteObject/PortableObject is actually immutable, so setting > hashcode > > for already constructed object looks dirty (set several bytes in array at > > certain offset). > > 2) It is not very efficient from implementation point of jdbc pojo > store > > (on more cycle over object fields with not very efficient access by name) > > > > So, I came to this solution: > > > > // Hash builder. > > public interface JdbcTypeHashBuilder { > > // Calculate hash code for specified value and field name. > > public int toHash(Object val, String typeName, String fieldName); > > > > // Calculated hash code. > > public int hash(); > > } > > > > // Default implementation of JdbcTypeHashBuilder. User could implement > its > > own if needed. > > public class JdbcTypeDefaultHashBuilder implements JdbcTypeHashBuilder { > > private int hash = 0; > > > > @Override public int toHash(Object val, String typeName, String > > fieldName) { > > hash = 31 * hash + (val != null ? val.hashCode() : 0); > > > > return hash; > > } > > > > @Override public int hash() { > > return hash; > > } > > } > > > > // Factory for creating default hash builder: > > public class JdbcTypeDefaultHashBuilderFactory implements > > Factory<JdbcTypeHashBuilder> { > > private static final long serialVersionUID = 0L; > > > > /** Instance of factory for reuse. */ > > public final static JdbcTypeDefaultHashBuilderFactory INSTANCE = new > > JdbcTypeDefaultHashBuilderFactory(); > > > > @Override public JdbcTypeHashBuilder create() { > > return new JdbcTypeDefaultHashBuilder(); > > } > > } > > > > And I add factory to CacheJdbcPojoStoreConfiguration { > > .... > > private Factory<JdbcTypeHashBuilder> hashBuilderFactory = > > JdbcTypeDefaultHashBuilderFactory.INSTANCE; > > } > > > > Now I could build PortableObject and calculate its hash at the same time: > > ... > > portableBuilder = ... > > > > hashBuilder = factory.create(); > > > > for (dbField: dbFields) { > > Object val = dbField.getValue(); > > > > portableBuilder.setField(dbField.getJavaName(), val) ; > > hashBuilder.toHash(val, typeName, dbField.getJavaName()); > > } > > > > return portableBuilder.hashCode(hashBuilder.hash()).build(); > > > > Thoughts? > > > > -- > > Alexey Kuznetsov > > GridGain Systems > > www.gridgain.com > > > -- Alexey Kuznetsov GridGain Systems www.gridgain.com