[Fix] correct @OneToMany on ObjectId

This commit is contained in:
Edouard DUPIN 2025-03-19 19:15:10 +01:00
parent 581c936bec
commit 84a968a426
3 changed files with 123 additions and 98 deletions

View File

@ -449,7 +449,7 @@ public class AnnotationTools {
if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) { if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
continue; continue;
} }
if (AnnotationTools.getFieldNameRaw(field).equals(name)) { if (field.getName().equals(name)) {
return true; return true;
} }
} }

View File

@ -223,16 +223,35 @@ public class DBAccessSQL extends DBAccess {
return out; return out;
} }
public byte[][] splitIntoGroupsOf12Bytes(final byte[] input) {
final int inputLength = input.length;
final int numOfGroups = (inputLength + 11) / 12; // Calculate the number of groups needed
final byte[][] groups = new byte[numOfGroups][12];
for (int i = 0; i < numOfGroups; i++) {
final int startIndex = i * 12;
final int endIndex = Math.min(startIndex + 12, inputLength);
groups[i] = Arrays.copyOfRange(input, startIndex, endIndex);
}
return groups;
}
public List<ObjectId> getListOfRawOIDs(final ResultSet rs, final int iii) throws SQLException, DataAccessException { public List<ObjectId> getListOfRawOIDs(final ResultSet rs, final int iii) throws SQLException, DataAccessException {
final byte[] trackString = rs.getBytes(iii); final byte[] trackString = rs.getBytes(iii);
if (rs.wasNull()) { if (rs.wasNull()) {
return null; return null;
} }
final byte[][] elements = splitIntoGroupsOf16Bytes(trackString); final byte[][] elements = splitIntoGroupsOf12Bytes(trackString);
final List<ObjectId> out = new ArrayList<>(); final List<ObjectId> out = new ArrayList<>();
for (final byte[] elem : elements) { for (final byte[] elem : elements) {
final ObjectId tmp = new ObjectId(elem); try {
out.add(tmp); final ObjectId tmp = new ObjectId(elem);
out.add(tmp);
} catch (final IllegalArgumentException ex) {
ex.printStackTrace();
LOGGER.error("Fail to parse the OID element: {}", elem);
}
} }
return out; return out;
} }
@ -1276,7 +1295,7 @@ public class DBAccessSQL extends DBAccess {
) throws Exception { ) throws Exception {
final boolean readAllfields = QueryOptions.readAllColomn(options); final boolean readAllfields = QueryOptions.readAllColomn(options);
final String tableName = AnnotationTools.getTableName(clazz, options); final String tableName = AnnotationTools.getTableName(clazz, options);
final String primaryKey = AnnotationTools.getPrimaryKeyField(clazz).getName(); final String primaryKey = AnnotationTools.getFieldNameRaw(AnnotationTools.getPrimaryKeyField(clazz));
boolean firstField = true; boolean firstField = true;
for (final Field elem : clazz.getFields()) { for (final Field elem : clazz.getFields()) {

View File

@ -231,109 +231,115 @@ public class AddOnOneToMany implements DataAccessAddOn {
final CountInOut count, final CountInOut count,
final QueryOptions options, final QueryOptions options,
final List<LazyGetter> lazyCall) throws Exception { final List<LazyGetter> lazyCall) throws Exception {
if (field.getType() != List.class) { try {
LOGGER.error("Can not OneToMany with other than List Model: {}", field.getType().getCanonicalName()); if (field.getType() != List.class) {
return; LOGGER.error("Can not OneToMany with other than List Model: {}", field.getType().getCanonicalName());
} return;
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType()) }
.getActualTypeArguments()[0]; final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType())
final OneToMany decorators = field.getDeclaredAnnotation(OneToMany.class); .getActualTypeArguments()[0];
if (decorators == null) { final OneToMany decorators = field.getDeclaredAnnotation(OneToMany.class);
return; if (decorators == null) {
} return;
if (objectClass == Long.class) { }
final List<Long> idList = ioDb.getListOfIds(rs, count.value, SEPARATOR_LONG); if (objectClass == Long.class) {
field.set(data, idList); final List<Long> idList = ioDb.getListOfIds(rs, count.value, SEPARATOR_LONG);
count.inc(); field.set(data, idList);
return;
} else if (objectClass == UUID.class) {
final List<UUID> idList = ioDb.getListOfRawUUIDs(rs, count.value);
field.set(data, idList);
count.inc();
return;
} else if (objectClass == ObjectId.class) {
final List<ObjectId> idList = ioDb.getListOfRawOIDs(rs, count.value);
field.set(data, idList);
count.inc();
return;
}
if (objectClass == decorators.targetEntity()) {
Long parentIdTmp = null;
UUID parendUuidTmp = null;
ObjectId parendOidTmp = null;
try {
final String modelData = rs.getString(count.value);
parentIdTmp = Long.valueOf(modelData);
count.inc(); count.inc();
} catch (final NumberFormatException ex) { return;
try { } else if (objectClass == UUID.class) {
final List<UUID> idList = ioDb.getListOfRawUUIDs(rs, count.value);
field.set(data, idList);
count.inc();
return;
} else if (objectClass == ObjectId.class) {
final List<ObjectId> idList = ioDb.getListOfRawOIDs(rs, count.value);
field.set(data, idList);
count.inc();
return;
}
if (objectClass == decorators.targetEntity()) {
final String destinationField = decorators.mappedBy();
final Field typeDestination = AnnotationTools.getFieldNamed(objectClass, destinationField);
final Class<?> destinationClass = typeDestination.getType();
Long parentIdTmp = null;
UUID parendUuidTmp = null;
ObjectId parendOidTmp = null;
if (destinationClass == String.class) {
final String modelData = rs.getString(count.value);
parentIdTmp = Long.valueOf(modelData);
count.inc();
} else if (destinationClass == UUID.class) {
final List<UUID> idList = ioDb.getListOfRawUUIDs(rs, count.value); final List<UUID> idList = ioDb.getListOfRawUUIDs(rs, count.value);
parendUuidTmp = idList.get(0); parendUuidTmp = idList.get(0);
count.inc(); count.inc();
} catch (final NumberFormatException ex2) { } else if (destinationClass == ObjectId.class) {
// TODO : How to manage ObjectId ==> I am not sure it works well...
final List<ObjectId> idList = ioDb.getListOfRawOIDs(rs, count.value); final List<ObjectId> idList = ioDb.getListOfRawOIDs(rs, count.value);
parendOidTmp = idList.get(0); parendOidTmp = idList.get(0);
count.inc(); count.inc();
} }
} final Long parentId = parentIdTmp;
final Long parentId = parentIdTmp; final UUID parendUuid = parendUuidTmp;
final UUID parendUuid = parendUuidTmp; final ObjectId parendOid = parendOidTmp;
final ObjectId parendOid = parendOidTmp; final String mappingKey = decorators.mappedBy();
final String mappingKey = decorators.mappedBy(); // We get the parent ID ... ==> need to request the list of elements
// We get the parent ID ... ==> need to request the list of elements if (objectClass == Long.class) {
if (objectClass == Long.class) { LOGGER.error("Need to retreive all primary key of all elements.");
LOGGER.error("Need to retreive all primary key of all elements"); //field.set(data, idList);
//field.set(data, idList); return;
return; } else if (objectClass == UUID.class) {
} else if (objectClass == UUID.class) { LOGGER.error("Need to retreive all primary key of all elements");
LOGGER.error("Need to retreive all primary key of all elements"); //field.set(data, idList);
//field.set(data, idList); return;
return; } else if (objectClass == ObjectId.class) {
} else if (objectClass == ObjectId.class) { LOGGER.error("Need to retreive all primary key of all elements");
LOGGER.error("Need to retreive all primary key of all elements"); //field.set(data, idList);
//field.set(data, idList); return;
return; }
} if (objectClass == decorators.targetEntity()) {
if (objectClass == decorators.targetEntity()) { if (decorators.fetch() == FetchType.EAGER) {
if (decorators.fetch() == FetchType.EAGER) { throw new DataAccessException("EAGER is not supported for list of element...");
throw new DataAccessException("EAGER is not supported for list of element..."); } else if (parentId != null) {
} else if (parentId != null) { // In the lazy mode, the request is done in asynchronous mode, they will be done after...
// In the lazy mode, the request is done in asynchronous mode, they will be done after... final LazyGetter lambda = () -> {
final LazyGetter lambda = () -> { @SuppressWarnings("unchecked")
@SuppressWarnings("unchecked") final Object foreignData = ioDb.getsWhere(decorators.targetEntity(),
final Object foreignData = ioDb.getsWhere(decorators.targetEntity(), new Condition(new QueryCondition(mappingKey, "=", parentId)));
new Condition(new QueryCondition(mappingKey, "=", parentId))); if (foreignData == null) {
if (foreignData == null) { return;
return; }
} field.set(data, foreignData);
field.set(data, foreignData); };
}; lazyCall.add(lambda);
lazyCall.add(lambda); } else if (parendUuid != null) {
} else if (parendUuid != null) { final LazyGetter lambda = () -> {
final LazyGetter lambda = () -> { @SuppressWarnings("unchecked")
@SuppressWarnings("unchecked") final Object foreignData = ioDb.getsWhere(decorators.targetEntity(),
final Object foreignData = ioDb.getsWhere(decorators.targetEntity(), new Condition(new QueryCondition(mappingKey, "=", parendUuid)));
new Condition(new QueryCondition(mappingKey, "=", parendUuid))); if (foreignData == null) {
if (foreignData == null) { return;
return; }
} field.set(data, foreignData);
field.set(data, foreignData); };
}; lazyCall.add(lambda);
lazyCall.add(lambda); } else if (parendOid != null) {
} else if (parendOid != null) { final LazyGetter lambda = () -> {
final LazyGetter lambda = () -> { @SuppressWarnings("unchecked")
@SuppressWarnings("unchecked") final Object foreignData = ioDb.getsWhere(decorators.targetEntity(),
final Object foreignData = ioDb.getsWhere(decorators.targetEntity(), new Condition(new QueryCondition(mappingKey, "=", parendOid)));
new Condition(new QueryCondition(mappingKey, "=", parendOid))); if (foreignData == null) {
if (foreignData == null) { return;
return; }
} field.set(data, foreignData);
field.set(data, foreignData); };
}; lazyCall.add(lambda);
lazyCall.add(lambda); }
} }
} }
} catch (final Exception ex) {
ex.printStackTrace();
LOGGER.error("Fail to parse remote {}", ex.getMessage());
} }
} }