diff --git a/src/main/java/org/warp/cowdb/Database.java b/src/main/java/org/warp/cowdb/Database.java index 795607b..996f3f0 100644 --- a/src/main/java/org/warp/cowdb/Database.java +++ b/src/main/java/org/warp/cowdb/Database.java @@ -1,8 +1,6 @@ package org.warp.cowdb; import com.esotericsoftware.kryo.Kryo; -import com.esotericsoftware.kryo.io.ByteBufferInput; -import com.esotericsoftware.kryo.io.ByteBufferInputStream; import com.esotericsoftware.kryo.io.Input; import com.esotericsoftware.kryo.io.Output; import it.unimi.dsi.fastutil.booleans.BooleanArrayList; @@ -15,7 +13,6 @@ import org.apache.commons.lang3.reflect.FieldUtils; import org.warp.jcwdb.ann.*; import java.io.ByteArrayOutputStream; -import java.io.IOError; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -29,7 +26,6 @@ import java.util.*; import java.util.function.Supplier; import static org.warp.cowdb.IBlocksMetadata.EMPTY_BLOCK_ID; -import static org.warp.cowdb.IBlocksMetadata.EMPTY_BLOCK_INFO; public class Database implements IDatabase { @@ -206,6 +202,8 @@ public class Database implements IDatabase { private final IDatabase database; private final DatabaseReferencesIO referencesIO; + private final Object accessLock = new Object(); + private Kryo kryo = new Kryo(); private DatabaseObjectsIO(IDatabase database, DatabaseReferencesIO referencesIO) { @@ -268,28 +266,30 @@ public class Database implements IDatabase { @Override public T loadEnhancedObject(long reference, Class objectType) throws IOException { - ByteBuffer buffer = referencesIO.readFromReference(reference); - if (buffer.limit() == 0) { - return null; + synchronized (accessLock) { + ByteBuffer buffer = referencesIO.readFromReference(reference); + if (buffer.limit() == 0) { + return null; + } + int fieldsCount = buffer.getInt(); + int methodsCount = buffer.getInt(); + long[] fieldRefs = new long[fieldsCount]; + long[] methodRefs = new long[methodsCount]; + for (int i = 0; i < fieldsCount; i++) { + fieldRefs[i] = buffer.getLong(); + } + for (int i = 0; i < methodsCount; i++) { + methodRefs[i] = buffer.getLong(); + } + return preloadEnhancedObject(objectType, fieldRefs, methodRefs); } - int fieldsCount = buffer.getInt(); - int methodsCount = buffer.getInt(); - long[] fieldRefs = new long[fieldsCount]; - long[] methodRefs = new long[methodsCount]; - for (int i = 0; i < fieldsCount; i++) { - fieldRefs[i] = buffer.getLong(); - } - for (int i = 0; i < methodsCount; i++) { - methodRefs[i] = buffer.getLong(); - } - return preloadEnhancedObject(objectType, fieldRefs, methodRefs); } @SuppressWarnings("unchecked") private Object loadData(DBDataType propertyType, long dataReference, Supplier> returnType) throws IOException { switch (propertyType) { - case DATABASE_OBJECT: + case ENHANCED_OBJECT: return loadEnhancedObject(dataReference, (Class) returnType.get()); case OBJECT: return loadObject(dataReference); @@ -338,7 +338,7 @@ public class Database implements IDatabase { case REFERENCES_LIST: setReferencesList(reference, (LongArrayList) loadedPropertyValue); break; - case DATABASE_OBJECT: + case ENHANCED_OBJECT: setEnhancedObject(reference, (EnhancedObject) loadedPropertyValue); break; } @@ -346,202 +346,240 @@ public class Database implements IDatabase { @Override public void setEnhancedObject(long reference, T value) throws IOException { - if (value != null) { - EnhancedObjectFullInfo objectFullInfo = value.getAllInfo(); - int totalSize = Integer.BYTES * 2 + objectFullInfo.getFieldReferences().length * Long.BYTES + objectFullInfo.getPropertyReferences().length * Long.BYTES; - ByteBuffer buffer = ByteBuffer.allocate(totalSize); - buffer.putInt(objectFullInfo.getFieldReferences().length); - buffer.putInt(objectFullInfo.getPropertyReferences().length); - for (int i = 0; i < objectFullInfo.getFieldReferences().length; i++) { - buffer.putLong(objectFullInfo.getFieldReferences()[i]); - } - for (int i = 0; i < objectFullInfo.getPropertyReferences().length; i++) { - buffer.putLong(objectFullInfo.getPropertyReferences()[i]); - } - for (int i = 0; i < objectFullInfo.getFieldReferences().length; i++) { - try { - setData(objectFullInfo.getFieldReferences()[i], objectFullInfo.getFieldTypes()[i], objectFullInfo.getFields()[i].get(value)); - } catch (IllegalAccessException e) { - throw new IOException(e); + synchronized (accessLock) { + if (value != null) { + EnhancedObjectFullInfo objectFullInfo = value.getAllInfo(); + int totalSize = Integer.BYTES * 2 + objectFullInfo.getFieldReferences().length * Long.BYTES + objectFullInfo.getPropertyReferences().length * Long.BYTES; + ByteBuffer buffer = ByteBuffer.allocate(totalSize); + buffer.putInt(objectFullInfo.getFieldReferences().length); + buffer.putInt(objectFullInfo.getPropertyReferences().length); + for (int i = 0; i < objectFullInfo.getFieldReferences().length; i++) { + buffer.putLong(objectFullInfo.getFieldReferences()[i]); } + for (int i = 0; i < objectFullInfo.getPropertyReferences().length; i++) { + buffer.putLong(objectFullInfo.getPropertyReferences()[i]); + } + for (int i = 0; i < objectFullInfo.getFieldReferences().length; i++) { + try { + setData(objectFullInfo.getFieldReferences()[i], objectFullInfo.getFieldTypes()[i], objectFullInfo.getFields()[i].get(value)); + } catch (IllegalAccessException e) { + throw new IOException(e); + } + } + for (int i = 0; i < objectFullInfo.getPropertyReferences().length; i++) { + setData(objectFullInfo.getPropertyReferences()[i], objectFullInfo.getPropertyTypes()[i], objectFullInfo.getLoadedPropertyValues()[i]); + } + buffer.flip(); + referencesIO.writeToReference(reference, totalSize, buffer); + } else { + referencesIO.writeToReference(reference, 0, null); } - for (int i = 0; i < objectFullInfo.getPropertyReferences().length; i++) { - setData(objectFullInfo.getPropertyReferences()[i], objectFullInfo.getPropertyTypes()[i], objectFullInfo.getLoadedPropertyValues()[i]); - } - buffer.flip(); - referencesIO.writeToReference(reference, totalSize, buffer); - } else { - referencesIO.writeToReference(reference, 0, null); } } @SuppressWarnings("unchecked") @Override public T loadObject(long reference) throws IOException { - ByteBuffer buffer = referencesIO.readFromReference(reference); - if (buffer.limit() == 0) { - return null; + synchronized (accessLock) { + ByteBuffer buffer = referencesIO.readFromReference(reference); + if (buffer.limit() == 0) { + return null; + } + buffer.rewind(); + byte[] data = buffer.array(); + return (T) kryo.readClassAndObject(new Input(data)); } - buffer.rewind(); - byte[] data = buffer.array(); - return (T) kryo.readClassAndObject(new Input(data)); } @Override public LongArrayList loadReferencesList(long reference) throws IOException { - ByteBuffer buffer = referencesIO.readFromReference(reference); - if (buffer.limit() == 0) { - return null; + synchronized (accessLock) { + ByteBuffer buffer = referencesIO.readFromReference(reference); + if (buffer.limit() == 0) { + return null; + } + int itemsCount = buffer.getInt(); + LongArrayList arrayList = new LongArrayList(); + for (int i = 0; i < itemsCount; i++) { + arrayList.add(buffer.getLong()); + } + return arrayList; } - int itemsCount = buffer.getInt(); - LongArrayList arrayList = new LongArrayList(); - for (int i = 0; i < itemsCount; i++) { - arrayList.add(buffer.getLong()); - } - return arrayList; } @Override public boolean loadBoolean(long reference) throws IOException { - ByteBuffer buffer = referencesIO.readFromReference(reference); - if (buffer.limit() == 0) { - return false; + synchronized (accessLock) { + ByteBuffer buffer = referencesIO.readFromReference(reference); + if (buffer.limit() == 0) { + return false; + } + return buffer.get() == 1; } - return buffer.get() == 1; } @Override public byte loadByte(long reference) throws IOException { - ByteBuffer buffer = referencesIO.readFromReference(reference); - if (buffer.limit() == 0) { - return 0; + synchronized (accessLock) { + ByteBuffer buffer = referencesIO.readFromReference(reference); + if (buffer.limit() == 0) { + return 0; + } + return buffer.get(); } - return buffer.get(); } @Override public short loadShort(long reference) throws IOException { - ByteBuffer buffer = referencesIO.readFromReference(reference); - if (buffer.limit() == 0) { - return 0; + synchronized (accessLock) { + ByteBuffer buffer = referencesIO.readFromReference(reference); + if (buffer.limit() == 0) { + return 0; + } + return buffer.getShort(); } - return buffer.getShort(); } @Override public char loadChar(long reference) throws IOException { - ByteBuffer buffer = referencesIO.readFromReference(reference); - if (buffer.limit() == 0) { - return 0; + synchronized (accessLock) { + ByteBuffer buffer = referencesIO.readFromReference(reference); + if (buffer.limit() == 0) { + return 0; + } + return buffer.getChar(); } - return buffer.getChar(); } @Override public int loadInt(long reference) throws IOException { - ByteBuffer buffer = referencesIO.readFromReference(reference); - if (buffer.limit() == 0) { - return 0; + synchronized (accessLock) { + ByteBuffer buffer = referencesIO.readFromReference(reference); + if (buffer.limit() == 0) { + return 0; + } + return buffer.getInt(); } - return buffer.getInt(); } @Override public long loadLong(long reference) throws IOException { - ByteBuffer buffer = referencesIO.readFromReference(reference); - if (buffer.limit() == 0) { - return 0; + synchronized (accessLock) { + ByteBuffer buffer = referencesIO.readFromReference(reference); + if (buffer.limit() == 0) { + return 0; + } + return buffer.getLong(); } - return buffer.getLong(); } @Override public void setObject(long reference, T value) throws IOException { - if (value != null) { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - Output output = new Output(outputStream); - kryo.writeClassAndObject(output, value); - output.flush(); - byte[] data = outputStream.toByteArray(); - ByteBuffer dataByteBuffer = ByteBuffer.wrap(data); - referencesIO.writeToReference(reference, data.length, dataByteBuffer); - } else { - referencesIO.writeToReference(reference, 0, null); + synchronized (accessLock) { + if (value != null) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + Output output = new Output(outputStream); + kryo.writeClassAndObject(output, value); + output.flush(); + byte[] data = outputStream.toByteArray(); + ByteBuffer dataByteBuffer = ByteBuffer.wrap(data); + referencesIO.writeToReference(reference, data.length, dataByteBuffer); + } else { + referencesIO.writeToReference(reference, 0, null); + } } } @Override public void setReferencesList(long reference, LongArrayList value) throws IOException { - if (value != null) { - int items = value.size(); - ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES * items + Integer.BYTES); - buffer.putInt(items); - for (int i = 0; i < items; i++) { - buffer.putLong(value.getLong(i)); + synchronized (accessLock) { + if (value != null) { + int items = value.size(); + ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES * items + Integer.BYTES); + buffer.putInt(items); + for (int i = 0; i < items; i++) { + buffer.putLong(value.getLong(i)); + } + buffer.flip(); + referencesIO.writeToReference(reference, buffer.limit(), buffer); + } else { + referencesIO.writeToReference(reference, 0, null); } - buffer.flip(); - referencesIO.writeToReference(reference, buffer.limit(), buffer); - } else { - referencesIO.writeToReference(reference, 0, null); } } @Override public void setBoolean(long reference, boolean value) throws IOException { - ByteBuffer buffer = ByteBuffer.allocate(Byte.BYTES); - buffer.put(value ? (byte) 1 : (byte) 0); - buffer.flip(); - referencesIO.writeToReference(reference, Byte.BYTES, buffer); + synchronized (accessLock) { + ByteBuffer buffer = ByteBuffer.allocate(Byte.BYTES); + buffer.put(value ? (byte) 1 : (byte) 0); + buffer.flip(); + referencesIO.writeToReference(reference, Byte.BYTES, buffer); + } } @Override public void setByte(long reference, byte value) throws IOException { - ByteBuffer buffer = ByteBuffer.allocate(Byte.BYTES); - buffer.put(value); - buffer.flip(); - referencesIO.writeToReference(reference, Byte.BYTES, buffer); + synchronized (accessLock) { + ByteBuffer buffer = ByteBuffer.allocate(Byte.BYTES); + buffer.put(value); + buffer.flip(); + referencesIO.writeToReference(reference, Byte.BYTES, buffer); + } } @Override public void setShort(long reference, short value) throws IOException { - ByteBuffer buffer = ByteBuffer.allocate(Short.BYTES); - buffer.putShort(value); - buffer.flip(); - referencesIO.writeToReference(reference, Short.BYTES, buffer); + synchronized (accessLock) { + ByteBuffer buffer = ByteBuffer.allocate(Short.BYTES); + buffer.putShort(value); + buffer.flip(); + referencesIO.writeToReference(reference, Short.BYTES, buffer); + } } @Override public void setChar(long reference, char value) throws IOException { - ByteBuffer buffer = ByteBuffer.allocate(Character.BYTES); - buffer.putChar(value); - buffer.flip(); - referencesIO.writeToReference(reference, Character.BYTES, buffer); + synchronized (accessLock) { + ByteBuffer buffer = ByteBuffer.allocate(Character.BYTES); + buffer.putChar(value); + buffer.flip(); + referencesIO.writeToReference(reference, Character.BYTES, buffer); + } } @Override public void setInt(long reference, int value) throws IOException { - ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES); - buffer.putInt(value); - buffer.flip(); - referencesIO.writeToReference(reference, Integer.BYTES, buffer); + synchronized (accessLock) { + ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES); + buffer.putInt(value); + buffer.flip(); + referencesIO.writeToReference(reference, Integer.BYTES, buffer); + } } @Override public void setLong(long reference, long value) throws IOException { - ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); - buffer.putLong(value); - buffer.flip(); - referencesIO.writeToReference(reference, Long.BYTES, buffer); + synchronized (accessLock) { + ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); + buffer.putLong(value); + buffer.flip(); + referencesIO.writeToReference(reference, Long.BYTES, buffer); + } } @Override public long newNullObject() throws IOException { - return referencesIO.allocateReference(); + synchronized (accessLock) { + return referencesIO.allocateReference(); + } } @Override public void loadProperty(EnhancedObject obj, int propertyId, Method property, DBDataType propertyType, long propertyUID) throws IOException { - obj.setProperty(propertyId, loadData(propertyType, propertyUID, property::getReturnType)); + synchronized (accessLock) { + obj.setProperty(propertyId, loadData(propertyType, propertyUID, property::getReturnType)); + } } @Override @@ -756,7 +794,11 @@ public class Database implements IDatabase { SeekableByteChannel currentFileChannel = metaFileChannel.position(reference * REF_META_BYTES_COUNT); currentFileChannel.read(buffer); buffer.flip(); - return buffer.getLong(); + long block = buffer.getLong(); + if (buffer.limit() == 0 || block == 0xFFFFFFFFFFFFFFFFL) { + return EMPTY_BLOCK_ID; + } + return block; } @Override diff --git a/src/main/java/org/warp/cowdb/lists/CowList.java b/src/main/java/org/warp/cowdb/lists/CowList.java index fcba1d4..b5a3d64 100644 --- a/src/main/java/org/warp/cowdb/lists/CowList.java +++ b/src/main/java/org/warp/cowdb/lists/CowList.java @@ -13,8 +13,7 @@ public abstract class CowList extends EnhancedObject { private final Object indicesAccessLock = new Object(); - @DBField(id = 0, type = DBDataType.REFERENCES_LIST) - private LongArrayList indices; + protected abstract LongArrayList getIndices(); public CowList() { @@ -24,14 +23,9 @@ public abstract class CowList extends EnhancedObject { super(database); } - @Override - public void initialize() throws IOException { - indices = new LongArrayList(); - } - public T get(int index) throws IOException { synchronized (indicesAccessLock) { - long uid = indices.getLong(index); + long uid = getIndices().getLong(index); return loadItem(uid); } } @@ -39,21 +33,22 @@ public abstract class CowList extends EnhancedObject { public void add(T value) throws IOException { long uid = database.getObjectsIO().newNullObject(); synchronized (indicesAccessLock) { - indices.add(uid); + getIndices().add(uid); writeItemToDisk(uid, value); } } public void update(int index, T value) throws IOException { synchronized (indicesAccessLock) { - set(index, value); + long uid = getIndices().getLong(index); + writeItemToDisk(uid, value); } } public void set(int index, T value) throws IOException { long uid = database.getObjectsIO().newNullObject(); synchronized (indicesAccessLock) { - indices.set(index, uid); + getIndices().set(index, uid); writeItemToDisk(uid, value); } } @@ -61,15 +56,15 @@ public abstract class CowList extends EnhancedObject { public void add(int index, T value) throws IOException { long uid = database.getObjectsIO().newNullObject(); synchronized (indicesAccessLock) { - indices.add(index, uid); + getIndices().add(index, uid); writeItemToDisk(uid, value); } } public T getLast() throws IOException { synchronized (indicesAccessLock) { - if (indices.size() > 0) { - return get(indices.size() - 1); + if (getIndices().size() > 0) { + return get(getIndices().size() - 1); } else { return null; } @@ -78,13 +73,13 @@ public abstract class CowList extends EnhancedObject { public boolean isEmpty() { synchronized (indicesAccessLock) { - return indices.size() <= 0; + return getIndices().size() <= 0; } } public int size() { synchronized (indicesAccessLock) { - return indices.size(); + return getIndices().size(); } } @@ -95,7 +90,7 @@ public abstract class CowList extends EnhancedObject { @Override public String toString() { return new StringJoiner(", ", CowList.class.getSimpleName() + "[", "]") - .add(indices.size() + " items") + .add(getIndices().size() + " items") .toString(); } } diff --git a/src/main/java/org/warp/cowdb/lists/EnhancedObjectCowList.java b/src/main/java/org/warp/cowdb/lists/EnhancedObjectCowList.java index e35f22f..2d18a1d 100644 --- a/src/main/java/org/warp/cowdb/lists/EnhancedObjectCowList.java +++ b/src/main/java/org/warp/cowdb/lists/EnhancedObjectCowList.java @@ -1,5 +1,6 @@ package org.warp.cowdb.lists; +import it.unimi.dsi.fastutil.longs.LongArrayList; import org.warp.cowdb.EnhancedObject; import org.warp.cowdb.IDatabase; import org.warp.jcwdb.ann.DBDataType; @@ -9,16 +10,30 @@ import java.io.IOException; public class EnhancedObjectCowList extends CowList { + @DBField(id = 0, type = DBDataType.REFERENCES_LIST) + private LongArrayList indices; + @DBField(id = 1, type = DBDataType.OBJECT) private Class type; + @Override + protected LongArrayList getIndices() { + return indices; + } + public EnhancedObjectCowList() { super(); } + @Override + public void initialize() throws IOException { + + } + public EnhancedObjectCowList(IDatabase database, Class type) throws IOException { super(database); this.type = type; + indices = new LongArrayList(); } @Override diff --git a/src/main/java/org/warp/cowdb/lists/ObjectCowList.java b/src/main/java/org/warp/cowdb/lists/ObjectCowList.java index 8902c27..78188bc 100644 --- a/src/main/java/org/warp/cowdb/lists/ObjectCowList.java +++ b/src/main/java/org/warp/cowdb/lists/ObjectCowList.java @@ -1,5 +1,6 @@ package org.warp.cowdb.lists; +import it.unimi.dsi.fastutil.longs.LongArrayList; import org.warp.cowdb.EnhancedObject; import org.warp.cowdb.IDatabase; import org.warp.jcwdb.ann.DBDataType; @@ -9,12 +10,26 @@ import java.io.IOException; public class ObjectCowList extends CowList { + @DBField(id = 0, type = DBDataType.REFERENCES_LIST) + private LongArrayList indices; + + @Override + protected LongArrayList getIndices() { + return indices; + } + public ObjectCowList() { super(); } public ObjectCowList(IDatabase database) throws IOException { super(database); + indices = new LongArrayList(); + } + + @Override + public void initialize() throws IOException { + } @Override diff --git a/src/main/java/org/warp/jcwdb/ann/DBDataType.java b/src/main/java/org/warp/jcwdb/ann/DBDataType.java index 9166a39..74dc214 100644 --- a/src/main/java/org/warp/jcwdb/ann/DBDataType.java +++ b/src/main/java/org/warp/jcwdb/ann/DBDataType.java @@ -1,7 +1,7 @@ package org.warp.jcwdb.ann; public enum DBDataType { - DATABASE_OBJECT, + ENHANCED_OBJECT, OBJECT, BOOLEAN, BYTE, diff --git a/src/test/java/org/warp/jcwdb/tests/NDBMultipleEnhancedObjects.java b/src/test/java/org/warp/jcwdb/tests/NDBMultipleEnhancedObjects.java index 82abb62..2e5e9a3 100644 --- a/src/test/java/org/warp/jcwdb/tests/NDBMultipleEnhancedObjects.java +++ b/src/test/java/org/warp/jcwdb/tests/NDBMultipleEnhancedObjects.java @@ -48,10 +48,10 @@ public class NDBMultipleEnhancedObjects { public static class RootTwoClasses extends EnhancedObject { - @DBField(id = 0, type = DBDataType.DATABASE_OBJECT) + @DBField(id = 0, type = DBDataType.ENHANCED_OBJECT) public NTestUtils.RootClass class1; - @DBField(id = 1, type = DBDataType.DATABASE_OBJECT) + @DBField(id = 1, type = DBDataType.ENHANCED_OBJECT) public NTestUtils.RootClass class2; public RootTwoClasses() { @@ -62,22 +62,22 @@ public class NDBMultipleEnhancedObjects { super(database); } - @DBPropertyGetter(id = 0, type = DBDataType.DATABASE_OBJECT) + @DBPropertyGetter(id = 0, type = DBDataType.ENHANCED_OBJECT) public NTestUtils.RootClass getClass3() { return getProperty(); } - @DBPropertySetter(id = 0, type = DBDataType.DATABASE_OBJECT) + @DBPropertySetter(id = 0, type = DBDataType.ENHANCED_OBJECT) public void setClass3(NTestUtils.RootClass value) { setProperty(value); } - @DBPropertyGetter(id = 1, type = DBDataType.DATABASE_OBJECT) + @DBPropertyGetter(id = 1, type = DBDataType.ENHANCED_OBJECT) public NTestUtils.RootClass getClass4() { return getProperty(); } - @DBPropertySetter(id = 1, type = DBDataType.DATABASE_OBJECT) + @DBPropertySetter(id = 1, type = DBDataType.ENHANCED_OBJECT) public void setClass4(NTestUtils.RootClass value) { setProperty(value); } diff --git a/src/test/java/org/warp/jcwdb/utils/NTestUtils.java b/src/test/java/org/warp/jcwdb/utils/NTestUtils.java index c6f13c5..55fe2f5 100644 --- a/src/test/java/org/warp/jcwdb/utils/NTestUtils.java +++ b/src/test/java/org/warp/jcwdb/utils/NTestUtils.java @@ -270,7 +270,7 @@ public class NTestUtils { @DBField(id = 7, type = DBDataType.REFERENCES_LIST) public LongArrayList field8; - @DBField(id = 8, type = DBDataType.DATABASE_OBJECT) + @DBField(id = 8, type = DBDataType.ENHANCED_OBJECT) public NSimplestClass field9; public RootClass() { @@ -321,7 +321,7 @@ public class NTestUtils { return getProperty(); } - @DBPropertyGetter(id = 8, type = DBDataType.DATABASE_OBJECT) + @DBPropertyGetter(id = 8, type = DBDataType.ENHANCED_OBJECT) public NSimplestClass get9() { return getProperty(); } @@ -366,7 +366,7 @@ public class NTestUtils { setProperty(val); } - @DBPropertySetter(id = 8, type = DBDataType.DATABASE_OBJECT) + @DBPropertySetter(id = 8, type = DBDataType.ENHANCED_OBJECT) public void set9(NSimplestClass val) { setProperty(val); }