[FEAT,API] review the manyToMany link table name to support better automatic models
- change link table name - nupport reverse add link, support table name with max size of 64 with hash reduce
This commit is contained in:
parent
401bd8318a
commit
464f844eed
@ -2,6 +2,8 @@ package org.atriasoft.archidata.dataAccess.addOnSQL;
|
|||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@ -26,6 +28,7 @@ import org.atriasoft.archidata.dataAccess.options.Condition;
|
|||||||
import org.atriasoft.archidata.dataAccess.options.OptionSpecifyType;
|
import org.atriasoft.archidata.dataAccess.options.OptionSpecifyType;
|
||||||
import org.atriasoft.archidata.dataAccess.options.OverrideTableName;
|
import org.atriasoft.archidata.dataAccess.options.OverrideTableName;
|
||||||
import org.atriasoft.archidata.exception.DataAccessException;
|
import org.atriasoft.archidata.exception.DataAccessException;
|
||||||
|
import org.atriasoft.archidata.exception.SystemException;
|
||||||
import org.atriasoft.archidata.tools.ConfigBaseVariable;
|
import org.atriasoft.archidata.tools.ConfigBaseVariable;
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -86,20 +89,99 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String generateLinkTableNameField(
|
public static String hashTo64Chars(final String input) {
|
||||||
|
try {
|
||||||
|
final MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||||
|
final byte[] hash = digest.digest(input.getBytes());
|
||||||
|
final StringBuilder hexString = new StringBuilder();
|
||||||
|
for (final byte b : hash) {
|
||||||
|
final String hex = Integer.toHexString(0xff & b);
|
||||||
|
if (hex.length() == 1) {
|
||||||
|
hexString.append('0');
|
||||||
|
}
|
||||||
|
hexString.append(hex);
|
||||||
|
}
|
||||||
|
return hexString.toString().substring(0, 64);
|
||||||
|
} catch (final NoSuchAlgorithmException e) {
|
||||||
|
throw new RuntimeException("Erreur lors du hachage de la chaîne", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String hashIfNeeded(final String input) {
|
||||||
|
if (input.length() > 64) {
|
||||||
|
// Keep only the 50 first chars
|
||||||
|
final String truncated = input.substring(0, Math.min(input.length(), 50));
|
||||||
|
final String fullHash = hashTo64Chars(input);
|
||||||
|
final String hashPart = fullHash.substring(0, 14);
|
||||||
|
return truncated + hashPart;
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
public record LinkTableWithMode(
|
||||||
|
String tableName,
|
||||||
|
boolean first) {}
|
||||||
|
|
||||||
|
public static LinkTableWithMode generateLinkTableNameField(
|
||||||
final String tableName,
|
final String tableName,
|
||||||
final Field field,
|
final Field field,
|
||||||
final QueryOptions options) throws Exception {
|
final QueryOptions options) throws Exception {
|
||||||
final FieldName name = AnnotationTools.getFieldName(field, options);
|
return generateLinkTableName(tableName, field);
|
||||||
return generateLinkTableName(tableName, name.inTable());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String generateLinkTableName(final String tableName, final String name) {
|
public static LinkTableWithMode generateLinkTableName(
|
||||||
String localName = name;
|
final String tableAName,
|
||||||
if (name.endsWith("s")) {
|
final String tableAFieldName,
|
||||||
localName = name.substring(0, name.length() - 1);
|
final String tableBName,
|
||||||
|
final String tableBFieldName) {
|
||||||
|
if (tableAName.compareTo(tableBName) < 0) {
|
||||||
|
return new LinkTableWithMode(
|
||||||
|
hashIfNeeded(tableAName + "_" + tableAFieldName + "_link_" + tableBName + "_" + tableBFieldName),
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
return tableName + "_link_" + localName;
|
return new LinkTableWithMode(
|
||||||
|
hashIfNeeded(tableBName + "_" + tableBFieldName + "_link_" + tableAName + "_" + tableAFieldName),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LinkTableWithMode generateLinkTableName(
|
||||||
|
final String tableAName,
|
||||||
|
final String tableAFieldName,
|
||||||
|
final ManyToMany manyToMany) throws SystemException {
|
||||||
|
if (manyToMany == null) {
|
||||||
|
throw new SystemException("@ManyMany is a null pointer " + tableAName);
|
||||||
|
}
|
||||||
|
if (manyToMany.targetEntity() == null) {
|
||||||
|
throw new SystemException("@ManyMany target entity is a null pointer: " + tableAName);
|
||||||
|
}
|
||||||
|
if (manyToMany.mappedBy() == null || manyToMany.mappedBy().isEmpty()) {
|
||||||
|
throw new SystemException("@ManyMany mapped by is not defined: " + tableAName);
|
||||||
|
}
|
||||||
|
final String tableNameRemote = AnnotationTools.getTableName(manyToMany.targetEntity());
|
||||||
|
return generateLinkTableName(tableAName, tableAFieldName, tableNameRemote, manyToMany.mappedBy());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LinkTableWithMode generateLinkTableName(final String tableAName, final Field field)
|
||||||
|
throws SystemException {
|
||||||
|
if (field == null) {
|
||||||
|
// TODO: throw !!!!
|
||||||
|
}
|
||||||
|
final FieldName columnName = AnnotationTools.getFieldName(field, null);
|
||||||
|
final ManyToMany manyToMany = AnnotationTools.get(field, ManyToMany.class);
|
||||||
|
return generateLinkTableName(tableAName, columnName.inTable(), manyToMany);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LinkTableWithMode generateLinkTableName(final Class<?> clazz, final String fieldName)
|
||||||
|
throws SystemException {
|
||||||
|
if (clazz == null) {
|
||||||
|
throw new SystemException("@ManyMany class reference is a null pointer ");
|
||||||
|
}
|
||||||
|
if (fieldName == null || fieldName.isEmpty() || fieldName.isBlank()) {
|
||||||
|
throw new SystemException("@ManyMany field of class reference is not defined");
|
||||||
|
}
|
||||||
|
final String tableName = AnnotationTools.getTableName(clazz);
|
||||||
|
final Field requestedField = AnnotationTools.getFieldNamed(clazz, fieldName);
|
||||||
|
return generateLinkTableName(tableName, requestedField);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateConcatQuery(
|
public void generateConcatQuery(
|
||||||
@ -112,18 +194,13 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
@NotNull final CountInOut count,
|
@NotNull final CountInOut count,
|
||||||
final QueryOptions options) throws Exception {
|
final QueryOptions options) throws Exception {
|
||||||
final ManyToMany manyToMany = AnnotationTools.getManyToMany(field);
|
final ManyToMany manyToMany = AnnotationTools.getManyToMany(field);
|
||||||
String linkTableName = generateLinkTableName(tableName, name);
|
final LinkTableWithMode linkTable = generateLinkTableName(tableName, name, manyToMany);
|
||||||
if (manyToMany.mappedBy() != null && manyToMany.mappedBy().length() != 0) {
|
|
||||||
// TODO: get the remote table name .....
|
|
||||||
final String remoteTableName = AnnotationTools.getTableName(manyToMany.targetEntity());
|
|
||||||
linkTableName = generateLinkTableName(remoteTableName, manyToMany.mappedBy());
|
|
||||||
}
|
|
||||||
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType())
|
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType())
|
||||||
.getActualTypeArguments()[0];
|
.getActualTypeArguments()[0];
|
||||||
final String tmpVariable = "tmp_" + Integer.toString(count.value);
|
final String tmpVariable = "tmp_" + Integer.toString(count.value);
|
||||||
querySelect.append(" (SELECT GROUP_CONCAT(");
|
querySelect.append(" (SELECT GROUP_CONCAT(");
|
||||||
querySelect.append(tmpVariable);
|
querySelect.append(tmpVariable);
|
||||||
if (manyToMany.mappedBy() == null || manyToMany.mappedBy().length() == 0) {
|
if (linkTable.first()) {
|
||||||
querySelect.append(".object2Id ");
|
querySelect.append(".object2Id ");
|
||||||
} else {
|
} else {
|
||||||
querySelect.append(".object1Id ");
|
querySelect.append(".object1Id ");
|
||||||
@ -147,7 +224,7 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
querySelect.append("') FROM ");
|
querySelect.append("') FROM ");
|
||||||
querySelect.append(linkTableName);
|
querySelect.append(linkTable.tableName());
|
||||||
querySelect.append(" ");
|
querySelect.append(" ");
|
||||||
querySelect.append(tmpVariable);
|
querySelect.append(tmpVariable);
|
||||||
querySelect.append(" WHERE ");
|
querySelect.append(" WHERE ");
|
||||||
@ -160,7 +237,7 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
querySelect.append(" = ");
|
querySelect.append(" = ");
|
||||||
querySelect.append(tmpVariable);
|
querySelect.append(tmpVariable);
|
||||||
querySelect.append(".");
|
querySelect.append(".");
|
||||||
if (manyToMany.mappedBy() == null || manyToMany.mappedBy().length() == 0) {
|
if (linkTable.first()) {
|
||||||
querySelect.append("object1Id ");
|
querySelect.append("object1Id ");
|
||||||
} else {
|
} else {
|
||||||
querySelect.append("object2Id ");
|
querySelect.append("object2Id ");
|
||||||
@ -168,7 +245,7 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
if (!"sqlite".equals(ConfigBaseVariable.getDBType())) {
|
if (!"sqlite".equals(ConfigBaseVariable.getDBType())) {
|
||||||
querySelect.append(" GROUP BY ");
|
querySelect.append(" GROUP BY ");
|
||||||
querySelect.append(tmpVariable);
|
querySelect.append(tmpVariable);
|
||||||
if (manyToMany.mappedBy() == null || manyToMany.mappedBy().length() == 0) {
|
if (linkTable.first()) {
|
||||||
querySelect.append(".object1Id");
|
querySelect.append(".object1Id");
|
||||||
} else {
|
} else {
|
||||||
querySelect.append(".object2Id");
|
querySelect.append(".object2Id");
|
||||||
@ -345,14 +422,14 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
"Can not ManyToMany with other than List<Long> or List<UUID> or List<ObjectId> Model: List<"
|
"Can not ManyToMany with other than List<Long> or List<UUID> or List<ObjectId> Model: List<"
|
||||||
+ objectClass.getCanonicalName() + ">");
|
+ objectClass.getCanonicalName() + ">");
|
||||||
}
|
}
|
||||||
final FieldName columnName = AnnotationTools.getFieldName(field, options);
|
final LinkTableWithMode linkTable = generateLinkTableName(tableName, field);
|
||||||
final String linkTableName = generateLinkTableName(tableName, columnName.inTable());
|
final String obj1 = linkTable.first ? "object1Id" : "object2Id";
|
||||||
|
final String obj2 = linkTable.first ? "object2Id" : "object1Id";
|
||||||
|
|
||||||
actions.add(() -> {
|
actions.add(() -> {
|
||||||
ioDb.deleteWhere(LinkTableGeneric.class, new OverrideTableName(linkTableName),
|
ioDb.deleteWhere(LinkTableGeneric.class, new OverrideTableName(linkTable.tableName()),
|
||||||
new Condition(new QueryCondition("object1Id", "=", localKey)),
|
new Condition(new QueryCondition(obj1, "=", localKey)),
|
||||||
new OptionSpecifyType("object1Id", localKey.getClass()),
|
new OptionSpecifyType(obj1, localKey.getClass()), new OptionSpecifyType(obj2, objectClass));
|
||||||
new OptionSpecifyType("object2Id", objectClass));
|
|
||||||
});
|
});
|
||||||
asyncInsert(ioDb, tableName, localKey, field, data, actions, options);
|
asyncInsert(ioDb, tableName, localKey, field, data, actions, options);
|
||||||
}
|
}
|
||||||
@ -385,13 +462,14 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
"Can not ManyToMany with other than List<Long> or List<UUID> or List<ObjectId> Model: List<"
|
"Can not ManyToMany with other than List<Long> or List<UUID> or List<ObjectId> Model: List<"
|
||||||
+ objectClass.getCanonicalName() + ">");
|
+ objectClass.getCanonicalName() + ">");
|
||||||
}
|
}
|
||||||
final FieldName columnName = AnnotationTools.getFieldName(field, options);
|
final LinkTableWithMode linkTable = generateLinkTableName(tableName, field);
|
||||||
final String linkTableName = generateLinkTableName(tableName, columnName.inTable());
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final List<Object> dataCasted = (List<Object>) data;
|
final List<Object> dataCasted = (List<Object>) data;
|
||||||
if (dataCasted.size() == 0) {
|
if (dataCasted.size() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final String obj1 = linkTable.first ? "object1Id" : "object2Id";
|
||||||
|
final String obj2 = linkTable.first ? "object2Id" : "object1Id";
|
||||||
final List<LinkTableGeneric> insertElements = new ArrayList<>();
|
final List<LinkTableGeneric> insertElements = new ArrayList<>();
|
||||||
for (final Object remoteKey : dataCasted) {
|
for (final Object remoteKey : dataCasted) {
|
||||||
if (remoteKey == null) {
|
if (remoteKey == null) {
|
||||||
@ -404,26 +482,23 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
actions.add(() -> {
|
actions.add(() -> {
|
||||||
ioDb.insertMultiple(insertElements, new OverrideTableName(linkTableName),
|
ioDb.insertMultiple(insertElements, new OverrideTableName(linkTable.tableName()),
|
||||||
new OptionSpecifyType("object1Id", localKey.getClass()),
|
new OptionSpecifyType(obj1, localKey.getClass()), new OptionSpecifyType(obj2, objectClass));
|
||||||
new OptionSpecifyType("object2Id", objectClass));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drop(final DBAccessSQL ioDb, final String tableName, final Field field, final QueryOptions options)
|
public void drop(final DBAccessSQL ioDb, final String tableName, final Field field, final QueryOptions options)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
final FieldName columnName = AnnotationTools.getFieldName(field, options);
|
final LinkTableWithMode linkTable = generateLinkTableName(tableName, field);
|
||||||
final String linkTableName = generateLinkTableName(tableName, columnName.inTable());
|
ioDb.drop(LinkTableGeneric.class, new OverrideTableName(linkTable.tableName()));
|
||||||
ioDb.drop(LinkTableGeneric.class, new OverrideTableName(linkTableName));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cleanAll(final DBAccessSQL ioDb, final String tableName, final Field field, final QueryOptions options)
|
public void cleanAll(final DBAccessSQL ioDb, final String tableName, final Field field, final QueryOptions options)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
final FieldName columnName = AnnotationTools.getFieldName(field, options);
|
final LinkTableWithMode linkTable = generateLinkTableName(tableName, field);
|
||||||
final String linkTableName = generateLinkTableName(tableName, columnName.inTable());
|
ioDb.cleanAll(LinkTableGeneric.class, new OverrideTableName(linkTable.tableName()));
|
||||||
ioDb.cleanAll(LinkTableGeneric.class, new OverrideTableName(linkTableName));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addLink(
|
public static void addLink(
|
||||||
@ -433,12 +508,14 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
final String column,
|
final String column,
|
||||||
final Object remoteKey) throws Exception {
|
final Object remoteKey) throws Exception {
|
||||||
if (ioDb instanceof final DBAccessSQL daSQL) {
|
if (ioDb instanceof final DBAccessSQL daSQL) {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
final LinkTableWithMode linkTable = generateLinkTableName(clazz, column);
|
||||||
final String linkTableName = generateLinkTableName(tableName, column);
|
final LinkTableGeneric insertElement = linkTable.first ? new LinkTableGeneric(localKey, remoteKey)
|
||||||
final LinkTableGeneric insertElement = new LinkTableGeneric(localKey, remoteKey);
|
: new LinkTableGeneric(remoteKey, localKey);
|
||||||
daSQL.insert(insertElement, new OverrideTableName(linkTableName),
|
final String obj1 = linkTable.first ? "object1Id" : "object2Id";
|
||||||
new OptionSpecifyType("object1Id", localKey.getClass()),
|
final String obj2 = linkTable.first ? "object2Id" : "object1Id";
|
||||||
new OptionSpecifyType("object2Id", remoteKey.getClass()));
|
daSQL.insert(insertElement, new OverrideTableName(linkTable.tableName()),
|
||||||
|
new OptionSpecifyType(obj1, localKey.getClass()),
|
||||||
|
new OptionSpecifyType(obj2, remoteKey.getClass()));
|
||||||
} else if (ioDb instanceof final DBAccessMorphia dam) {
|
} else if (ioDb instanceof final DBAccessMorphia dam) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -454,13 +531,14 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
final String column,
|
final String column,
|
||||||
final Object remoteKey) throws Exception {
|
final Object remoteKey) throws Exception {
|
||||||
if (ioDb instanceof final DBAccessSQL daSQL) {
|
if (ioDb instanceof final DBAccessSQL daSQL) {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
final LinkTableWithMode linkTable = generateLinkTableName(clazz, column);
|
||||||
final String linkTableName = generateLinkTableName(tableName, column);
|
final String obj1 = linkTable.first ? "object1Id" : "object2Id";
|
||||||
return daSQL.deleteWhere(LinkTableGeneric.class, new OverrideTableName(linkTableName),
|
final String obj2 = linkTable.first ? "object2Id" : "object1Id";
|
||||||
new Condition(new QueryAnd(new QueryCondition("object1Id", "=", localKey),
|
return daSQL.deleteWhere(LinkTableGeneric.class, new OverrideTableName(linkTable.tableName()),
|
||||||
new QueryCondition("object2Id", "=", remoteKey))),
|
new Condition(new QueryAnd(new QueryCondition(obj1, "=", localKey),
|
||||||
new OptionSpecifyType("object1Id", localKey.getClass()),
|
new QueryCondition(obj2, "=", remoteKey))),
|
||||||
new OptionSpecifyType("object2Id", remoteKey.getClass()));
|
new OptionSpecifyType(obj1, localKey.getClass()),
|
||||||
|
new OptionSpecifyType(obj2, remoteKey.getClass()));
|
||||||
} else if (ioDb instanceof final DBAccessMorphia dam) {
|
} else if (ioDb instanceof final DBAccessMorphia dam) {
|
||||||
return 0L;
|
return 0L;
|
||||||
} else {
|
} else {
|
||||||
@ -481,18 +559,21 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
final int fieldId,
|
final int fieldId,
|
||||||
final QueryOptions options) throws Exception {
|
final QueryOptions options) throws Exception {
|
||||||
final ManyToMany manyToMany = AnnotationTools.getManyToMany(field);
|
final ManyToMany manyToMany = AnnotationTools.getManyToMany(field);
|
||||||
if (manyToMany.mappedBy() != null && manyToMany.mappedBy().length() != 0) {
|
if (manyToMany.mappedBy() == null || manyToMany.mappedBy().length() == 0) {
|
||||||
// not the reference model to create base:
|
throw new SystemException("MappedBy must be set in ManyMany: " + tableName + " " + field.getName());
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
final String linkTableName = generateLinkTableNameField(tableName, field, options);
|
final LinkTableWithMode linkTable = generateLinkTableNameField(tableName, field, options);
|
||||||
final QueryOptions options2 = new QueryOptions(new OverrideTableName(linkTableName));
|
if (linkTable.first()) {
|
||||||
|
final QueryOptions options2 = new QueryOptions(new OverrideTableName(linkTable.tableName()));
|
||||||
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType())
|
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType())
|
||||||
.getActualTypeArguments()[0];
|
.getActualTypeArguments()[0];
|
||||||
final Class<?> primaryType = primaryField.getType();
|
final Class<?> primaryType = primaryField.getType();
|
||||||
options2.add(new OptionSpecifyType("object1Id", primaryType));
|
final String obj1 = linkTable.first ? "object1Id" : "object2Id";
|
||||||
options2.add(new OptionSpecifyType("object2Id", objectClass));
|
final String obj2 = linkTable.first ? "object2Id" : "object1Id";
|
||||||
|
options2.add(new OptionSpecifyType(obj1, primaryType));
|
||||||
|
options2.add(new OptionSpecifyType(obj2, objectClass));
|
||||||
final List<String> sqlCommand = DataFactory.createTable(LinkTableGeneric.class, options2);
|
final List<String> sqlCommand = DataFactory.createTable(LinkTableGeneric.class, options2);
|
||||||
postActionList.addAll(sqlCommand);
|
postActionList.addAll(sqlCommand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -13,6 +13,6 @@ public class TypeManyToManyLongRoot extends GenericData {
|
|||||||
|
|
||||||
public String otherData;
|
public String otherData;
|
||||||
|
|
||||||
@ManyToMany(fetch = FetchType.LAZY, targetEntity = TypeManyToManyLongRemote.class)
|
@ManyToMany(fetch = FetchType.LAZY, targetEntity = TypeManyToManyLongRemote.class, mappedBy = "remoteToParent")
|
||||||
public List<Long> remote;
|
public List<Long> remote;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,6 @@ public class TypeManyToManyLongRootExpand extends GenericData {
|
|||||||
|
|
||||||
public String otherData;
|
public String otherData;
|
||||||
|
|
||||||
@ManyToMany(fetch = FetchType.LAZY, targetEntity = TypeManyToManyLongRemote.class)
|
@ManyToMany(fetch = FetchType.LAZY, targetEntity = TypeManyToManyLongRemote.class, mappedBy = "remoteToParent")
|
||||||
public List<TypeManyToManyLongRemote> remote;
|
public List<TypeManyToManyLongRemote> remote;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,6 @@ public class TypeManyToManyOIDRoot extends OIDGenericData {
|
|||||||
|
|
||||||
public String otherData;
|
public String otherData;
|
||||||
|
|
||||||
@ManyToMany(fetch = FetchType.LAZY, targetEntity = TypeManyToManyOIDRemote.class)
|
@ManyToMany(fetch = FetchType.LAZY, targetEntity = TypeManyToManyOIDRemote.class, mappedBy = "remoteToParent")
|
||||||
public List<ObjectId> remote;
|
public List<ObjectId> remote;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,6 @@ public class TypeManyToManyOIDRootExpand extends OIDGenericData {
|
|||||||
|
|
||||||
public String otherData;
|
public String otherData;
|
||||||
|
|
||||||
@ManyToMany(fetch = FetchType.LAZY, targetEntity = TypeManyToManyOIDRemote.class)
|
@ManyToMany(fetch = FetchType.LAZY, targetEntity = TypeManyToManyOIDRemote.class, mappedBy = "remoteToParent")
|
||||||
public List<TypeManyToManyOIDRemote> remote;
|
public List<TypeManyToManyOIDRemote> remote;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user