use of javax.persistence.ManyToMany in project eweb4j-framework by laiweiwei.
the class ManyToManyDAO method select.
/**
* 多对多级联查询
* 1.当主对象没有包含任何一个关联对象时,默认查询所有与之关联的对象
* 2.当主对象中包含了关联对象时(含有其toRefVal值),则只查询这些关联的对象
*
*/
public void select() throws DAOException {
if (this.fields == null || this.fields.size() == 0)
return;
// select tarClass from {tarTable} t, {relTable} r where r.to = t.toRefCol and r.from = {fromRefVal} order by r.xxx desc
// select %s from {tarTable} where {toRefCol} in (select {to} from {relTable} where {from} = {fromRefVal} order by xxx desc)
// String format = "SELECT %s FROM %s WHERE %s IN (SELECT %s FROM %s WHERE %s = ? %s)";
final String format = "select %s from %s, %s r where r.%s = %s.%s and r.%s = ? %s ";
for (Field f : fields) {
Method tarGetter = ru.getGetter(f.getName());
if (tarGetter == null)
continue;
ManyToMany ann = tarGetter.getAnnotation(ManyToMany.class);
if (ann == null) {
ann = f.getAnnotation(ManyToMany.class);
if (ann == null)
continue;
}
JoinTable join = tarGetter.getAnnotation(JoinTable.class);
if (join == null) {
join = f.getAnnotation(JoinTable.class);
if (join == null)
continue;
}
JoinColumn[] froms = join.joinColumns();
if (froms == null || froms.length == 0)
continue;
JoinColumn[] tos = join.inverseJoinColumns();
if (tos == null || tos.length == 0)
continue;
// 多对多关系目标Class
Class<?> tarClass = ann.targetEntity();
if (void.class.isAssignableFrom(tarClass)) {
tarClass = ClassUtil.getGenericType(f);
}
String tarTable = ORMConfigBeanUtil.getTable(tarClass, true);
OrderBy orderAnn = tarGetter.getAnnotation(OrderBy.class);
if (orderAnn == null)
orderAnn = f.getAnnotation(OrderBy.class);
String orderBy = "";
if (orderAnn != null && orderAnn.value().trim().length() > 0)
orderBy = " ORDER BY " + orderAnn.value().replace("t.", tarClass.getSimpleName().toLowerCase() + ".");
// 目标类对应的数据库表Id字段
String toRefCol = tos[0].referencedColumnName();
if (toRefCol == null || toRefCol.trim().length() == 0)
toRefCol = ORMConfigBeanUtil.getIdColumn(tarClass);
String toRefField = ORMConfigBeanUtil.getField(tarClass, toRefCol);
// 目标类在第三方关系表中的字段名
String to = tos[0].name();
// 第三方关系表
String relTable = join.name();
// 主类在第三方关系表中的字段名
String from = froms[0].name();
String fromRefCol = froms[0].referencedColumnName();
if (fromRefCol == null || fromRefCol.trim().length() == 0)
fromRefCol = ORMConfigBeanUtil.getIdColumn(t);
String fromRefField = ORMConfigBeanUtil.getField(t.getClass(), fromRefCol);
try {
List<?> tarList = null;
tarList = (List<?>) tarGetter.invoke(t);
if (tarList != null && tarList.size() > 0) {
for (int i = 0; i < tarList.size(); i++) {
Object tarObj = tarList.get(i);
ReflectUtil tarRu = new ReflectUtil(tarObj);
Method toRefFieldGetter = tarRu.getGetter(toRefField);
if (toRefFieldGetter == null)
throw new DAOException("can not find the 'to ref field -> " + toRefField + "' of " + tarClass + " 's getter method", null);
Object _obj = toRefFieldGetter.invoke(tarObj);
if (_obj == null)
continue;
String toRefVal = String.valueOf(_obj);
// 查询 select %s from {tarTable} where {tarIdColumn} = {tarIdVal}
tarObj = DAOFactory.getSelectDAO(dsName).selectOne(tarClass, new String[] { toRefField }, new String[] { toRefVal });
}
} else {
// "select %s from %s, %s r where r.%s = %s.%s and r.%s = ? %s "
// select tarClass from {tarTable} t, {relTable} r where r.to = t.toRefCol and r.from = ? order by r.xxx desc
String sql = String.format(format, ORMConfigBeanUtil.getSelectAllColumn(tarClass), tarTable, relTable, to, tarClass.getSimpleName().toLowerCase(), toRefCol, from, orderBy);
// 从数据库中取出与当前主对象fromRefCol关联的所有目标对象,
Method fromRefFieldGetter = ru.getGetter(fromRefField);
if (fromRefFieldGetter == null)
throw new DAOException("can not find the 'from ref field -> " + fromRefField + "' of " + t.getClass() + " 's getter method", null);
Object _obj = fromRefFieldGetter.invoke(t);
String fromRefVal = null;
if (_obj != null)
fromRefVal = String.valueOf(_obj);
tarList = DAOFactory.getSelectDAO(dsName).selectBySQL(tarClass, sql, fromRefVal);
}
// 并注入到当前主对象的属性中
Method tarSetter = ru.getSetter(f.getName());
tarSetter.invoke(t, tarList);
} catch (Exception e) {
e.printStackTrace();
throw new DAOException("", e);
}
}
}
use of javax.persistence.ManyToMany in project eweb4j-framework by laiweiwei.
the class PojoAnnotationConfig method getProperties.
private static List<Property> getProperties(Class<?> clazz, final List<Property> pList, final boolean requireSuper, Log log) throws Throwable {
List<Property> result = new ArrayList<Property>();
ReflectUtil ru;
try {
ru = new ReflectUtil(clazz);
ru.setRequiredSuper(requireSuper);
} catch (Throwable e) {
log.warn(e.toString(), e);
throw e;
}
for (Field f : ru.getFields()) {
if (Collection.class.isAssignableFrom(f.getType()))
continue;
String name = f.getName();
Method getter = ru.getGetter(name);
if (getter == null)
continue;
Ignore igAnn = f.getAnnotation(Ignore.class);
if (igAnn == null)
igAnn = getter.getAnnotation(Ignore.class);
if (igAnn != null)
continue;
Transient trans = f.getAnnotation(Transient.class);
if (trans == null)
trans = getter.getAnnotation(Transient.class);
if (trans != null)
continue;
OneToMany manyAnn = getter.getAnnotation(OneToMany.class);
if (manyAnn != null)
continue;
else {
manyAnn = f.getAnnotation(OneToMany.class);
if (manyAnn != null)
continue;
}
ManyToMany manyManyAnn = getter.getAnnotation(ManyToMany.class);
if (manyManyAnn != null)
continue;
else {
manyManyAnn = f.getAnnotation(ManyToMany.class);
if (manyManyAnn != null)
continue;
}
Property p = new Property();
if (Long.class.isAssignableFrom(f.getType()) || long.class.isAssignableFrom(f.getType()))
p.setSize("20");
else if (Integer.class.isAssignableFrom(f.getType()) || int.class.isAssignableFrom(f.getType()))
p.setSize("8");
else if (String.class.isAssignableFrom(f.getType()))
p.setSize("255");
else if (Boolean.class.isAssignableFrom(f.getType()) || boolean.class.isAssignableFrom(f.getType()))
p.setSize("");
else if (Float.class.isAssignableFrom(f.getType()) || float.class.isAssignableFrom(f.getType()))
p.setSize("8");
Id idAnn = getter.getAnnotation(Id.class);
if (idAnn == null)
idAnn = f.getAnnotation(Id.class);
if (idAnn != null) {
if (pList != null && hasIdProperty(pList))
continue;
p.setAutoIncrement("1");
p.setPk("1");
p.setSize("20");
}
Column colAnn = getter.getAnnotation(Column.class);
if (colAnn == null) {
colAnn = f.getAnnotation(Column.class);
}
String column = colAnn == null ? "" : colAnn.name();
column = "".equals(column.trim()) ? name : column;
p.setName(name);
p.setColumn(column);
p.setType(f.getType().getName());
p.setNotNull("false");
if (colAnn != null) {
// int size = colAnn.length();
p.setNotNull(String.valueOf(!colAnn.nullable()));
p.setUnique(String.valueOf(colAnn.unique()));
}
if (ClassUtil.isPojo(f.getType())) {
OneToOne oneAnn = getter.getAnnotation(OneToOne.class);
if (oneAnn == null)
oneAnn = f.getAnnotation(OneToOne.class);
ManyToOne manyToOneAnn = null;
if (oneAnn == null) {
manyToOneAnn = getter.getAnnotation(ManyToOne.class);
if (manyToOneAnn == null)
manyToOneAnn = f.getAnnotation(ManyToOne.class);
}
if (oneAnn != null || manyToOneAnn != null) {
if (oneAnn != null)
p.setType(PropType.ONE_ONE);
else
p.setType(PropType.MANY_ONE);
JoinColumn joinColumn = getter.getAnnotation(JoinColumn.class);
if (joinColumn == null)
joinColumn = f.getAnnotation(JoinColumn.class);
if (joinColumn != null && joinColumn.name().trim().length() > 0)
p.setColumn(joinColumn.name());
else
p.setColumn(f.getName() + "_id");
p.setRelProperty(null);
String refCol = null;
if (joinColumn != null && joinColumn.referencedColumnName().trim().length() > 0) {
refCol = joinColumn.referencedColumnName();
if (refCol != null && refCol.trim().length() > 0) {
String relField = ORMConfigBeanUtil.getField(f.getType(), refCol);
if (relField != null && relField.trim().length() > 0)
p.setRelProperty(relField);
}
}
p.setRelClass(f.getType());
p.setSize("20");
}
}
result.add(p);
}
return result;
}
use of javax.persistence.ManyToMany in project eweb4j-framework by laiweiwei.
the class ManyToManyDAO method delete.
/**
* 多对多级联删除
* 1.如果主对象不存在与数据库,不处理
* 2.否则,检查当前主对象中的关联对象,如果关联对象为空,则删除所有与主对象有关的关联关系。
* 3.如果当前主对象中含有关联对象,则删除这些关联对象与主对象的关系
* 4.不会删除主对象
*
*/
public void delete() throws DAOException {
if (this.fields == null || this.fields.size() == 0)
return;
// "delete from {relTable} WHERE {from} = {fromRefVal} ;"
String format = "delete from %s WHERE %s = ? ";
for (Field f : fields) {
Method tarGetter = ru.getGetter(f.getName());
if (tarGetter == null)
continue;
ManyToMany ann = tarGetter.getAnnotation(ManyToMany.class);
if (ann == null) {
ann = f.getAnnotation(ManyToMany.class);
if (ann == null)
continue;
}
JoinTable join = tarGetter.getAnnotation(JoinTable.class);
if (join == null) {
join = f.getAnnotation(JoinTable.class);
if (join == null)
continue;
}
JoinColumn[] froms = join.joinColumns();
if (froms == null || froms.length == 0)
continue;
JoinColumn[] tos = join.inverseJoinColumns();
if (tos == null || tos.length == 0)
continue;
String relTable = join.name();
String from = froms[0].name();
String fromRefCol = froms[0].referencedColumnName();
if (fromRefCol == null || fromRefCol.trim().length() == 0)
fromRefCol = ORMConfigBeanUtil.getIdColumn(t);
String fromRefField = ORMConfigBeanUtil.getField(t.getClass(), fromRefCol);
Method fromRefFieldGetter = ru.getGetter(fromRefField);
if (fromRefFieldGetter == null)
throw new DAOException("can not find the 'from ref field -> " + fromRefField + "' of " + t.getClass() + " 's getter method", null);
String fromRefVal = null;
try {
Object _obj = fromRefFieldGetter.invoke(t);
if (_obj == null)
continue;
fromRefVal = String.valueOf(_obj);
} catch (Exception e) {
throw new DAOException("can not get the from ref val of " + t.getClass(), e);
}
List<?> tarList = null;
try {
tarList = (List<?>) tarGetter.invoke(t);
} catch (Exception e) {
throw new DAOException(tarGetter + " invoke exception, can not get the " + f.getName() + " objs ", e);
}
if (tarList == null || tarList.size() == 0) {
String sql = String.format(format, relTable, from);
// 删除所有关联记录
DAOFactory.getUpdateDAO(dsName).updateBySQLWithArgs(sql, fromRefVal);
} else {
// 删除指定关联的记录
Class<?> tarClass = ann.targetEntity();
if (void.class.isAssignableFrom(tarClass)) {
tarClass = ClassUtil.getGenericType(f);
}
String to = tos[0].name();
String toRefCol = tos[0].referencedColumnName();
if (toRefCol == null || toRefCol.trim().length() == 0)
toRefCol = ORMConfigBeanUtil.getIdColumn(tarClass);
String toRefField = ORMConfigBeanUtil.getField(tarClass, toRefCol);
// "delete from {relTable} where {from} = {fromRefVal} and to = {toRefVal}"
String _format = "delete from %s where %s = ? and %s = ?";
for (int i = 0; i < tarList.size(); i++) {
Object tarObj = tarList.get(i);
if (tarObj == null)
continue;
ReflectUtil tarRu = new ReflectUtil(tarObj);
Method toRefFieldGetter = tarRu.getGetter(toRefField);
if (toRefFieldGetter == null)
throw new DAOException("can not find the 'to ref field -> " + toRefField + "' of " + tarClass + " 's getter method", null);
String toRefVal = null;
try {
Object _obj = toRefFieldGetter.invoke(tarObj);
if (_obj == null)
continue;
toRefVal = String.valueOf(_obj);
} catch (Exception e) {
throw new DAOException("can not get the to ref val of " + tarClass, e);
}
if (DAOFactory.getSelectDAO(dsName).selectOne(tarClass, new String[] { toRefField }, new String[] { toRefVal }) == null)
continue;
String _sql = String.format(_format, relTable, from, to);
DAOFactory.getUpdateDAO(dsName).updateBySQLWithArgs(_sql, fromRefVal, toRefVal);
}
}
}
}
use of javax.persistence.ManyToMany in project orientdb by orientechnologies.
the class OObjectEntitySerializer method getSpecifiedMultiLinkedType.
public static Class<?> getSpecifiedMultiLinkedType(final Field f) {
final OneToMany m1 = f.getAnnotation(OneToMany.class);
if (m1 != null && !m1.targetEntity().equals(void.class))
return m1.targetEntity();
final ManyToMany m3 = f.getAnnotation(ManyToMany.class);
if (m3 != null && !m3.targetEntity().equals(void.class))
return m3.targetEntity();
return null;
}
use of javax.persistence.ManyToMany in project orientdb by orientechnologies.
the class OObjectEntitySerializer method registerClass.
/**
* Registers the class informations that will be used in serialization, deserialization and lazy loading of it. If already
* registered does nothing.
*
* @param iClass
* :- the Class<?> to register
* @param forceReload whether or not to force the reload of the schema before registering
*/
@SuppressWarnings("unchecked")
public static synchronized void registerClass(final Class<?> iClass, boolean forceReload) {
if (!ODatabaseRecordThreadLocal.INSTANCE.isDefined() || ODatabaseRecordThreadLocal.INSTANCE.get().isClosed())
return;
final OObjectEntitySerializedSchema serializedSchema = getCurrentSerializedSchema();
if (serializedSchema == null)
return;
if (Proxy.class.isAssignableFrom(iClass) || iClass.isEnum() || OReflectionHelper.isJavaType(iClass) || iClass.isAnonymousClass() || serializedSchema.classes.contains(iClass)) {
return;
}
boolean reloadSchema = false;
boolean automaticSchemaGeneration = false;
final ODatabaseDocumentInternal db = ODatabaseRecordThreadLocal.INSTANCE.get();
final OSchema oSchema = db.getMetadata().getSchema();
if (forceReload) {
oSchema.reload();
}
if (!oSchema.existsClass(iClass.getSimpleName())) {
if (Modifier.isAbstract(iClass.getModifiers()))
oSchema.createAbstractClass(iClass.getSimpleName());
else
oSchema.createClass(iClass.getSimpleName());
reloadSchema = true;
if (db.getDatabaseOwner() instanceof OObjectDatabaseTx)
automaticSchemaGeneration = ((OObjectDatabaseTx) db.getDatabaseOwner()).isAutomaticSchemaGeneration();
}
for (Class<?> currentClass = iClass; currentClass != Object.class; ) {
if (!serializedSchema.classes.contains(currentClass)) {
serializedSchema.classes.add(currentClass);
Class<?> fieldType;
for (Field f : currentClass.getDeclaredFields()) {
final String fieldName = f.getName();
final int fieldModifier = f.getModifiers();
boolean transientField = false;
if (Modifier.isStatic(fieldModifier) || Modifier.isFinal(fieldModifier) || Modifier.isNative(fieldModifier) || Modifier.isTransient(fieldModifier)) {
List<String> classTransientFields = serializedSchema.transientFields.get(currentClass);
if (classTransientFields == null)
classTransientFields = new ArrayList<String>();
classTransientFields.add(fieldName);
serializedSchema.transientFields.put(currentClass, classTransientFields);
transientField = true;
}
if (fieldName.equals("this$0")) {
List<String> classTransientFields = serializedSchema.transientFields.get(currentClass);
if (classTransientFields == null)
classTransientFields = new ArrayList<String>();
classTransientFields.add(fieldName);
serializedSchema.transientFields.put(currentClass, classTransientFields);
transientField = true;
}
if (OObjectSerializerHelper.jpaTransientClass != null) {
Annotation ann = f.getAnnotation(OObjectSerializerHelper.jpaTransientClass);
if (ann != null) {
// @Transient DEFINED
List<String> classTransientFields = serializedSchema.transientFields.get(currentClass);
if (classTransientFields == null)
classTransientFields = new ArrayList<String>();
classTransientFields.add(fieldName);
serializedSchema.transientFields.put(currentClass, classTransientFields);
transientField = true;
}
}
if (!transientField) {
List<String> allClassFields = serializedSchema.allFields.get(currentClass);
if (allClassFields == null)
allClassFields = new ArrayList<String>();
allClassFields.add(fieldName);
serializedSchema.allFields.put(currentClass, allClassFields);
}
if (OObjectSerializerHelper.jpaOneToOneClass != null) {
Annotation ann = f.getAnnotation(OObjectSerializerHelper.jpaOneToOneClass);
if (ann != null) {
// @OneToOne DEFINED
OneToOne oneToOne = ((OneToOne) ann);
if (checkCascadeDelete(oneToOne)) {
addCascadeDeleteField(currentClass, fieldName);
}
if (checkFetchLazy(oneToOne)) {
addFetchLazyField(currentClass, fieldName);
}
}
}
if (OObjectSerializerHelper.jpaOneToManyClass != null) {
Annotation ann = f.getAnnotation(OObjectSerializerHelper.jpaOneToManyClass);
if (ann != null) {
// @OneToMany DEFINED
OneToMany oneToMany = ((OneToMany) ann);
if (checkCascadeDelete(oneToMany)) {
addCascadeDeleteField(currentClass, fieldName);
}
}
}
if (OObjectSerializerHelper.jpaManyToManyClass != null) {
Annotation ann = f.getAnnotation(OObjectSerializerHelper.jpaManyToManyClass);
if (ann != null) {
// @OneToMany DEFINED
ManyToMany manyToMany = ((ManyToMany) ann);
if (checkCascadeDelete(manyToMany)) {
addCascadeDeleteField(currentClass, fieldName);
}
}
}
fieldType = f.getType();
if (Collection.class.isAssignableFrom(fieldType) || fieldType.isArray() || Map.class.isAssignableFrom(fieldType)) {
fieldType = OReflectionHelper.getGenericMultivalueType(f);
}
if (isToSerialize(fieldType)) {
Map<Field, Class<?>> serializeClass = serializedSchema.serializedFields.get(currentClass);
if (serializeClass == null)
serializeClass = new HashMap<Field, Class<?>>();
serializeClass.put(f, fieldType);
serializedSchema.serializedFields.put(currentClass, serializeClass);
}
// CHECK FOR DIRECT-BINDING
boolean directBinding = true;
if (f.getAnnotation(OAccess.class) == null || f.getAnnotation(OAccess.class).value() == OAccess.OAccessType.PROPERTY)
directBinding = true;
else // JPA 2+ AVAILABLE?
if (OObjectSerializerHelper.jpaAccessClass != null) {
Annotation ann = f.getAnnotation(OObjectSerializerHelper.jpaAccessClass);
if (ann != null) {
directBinding = true;
}
}
if (directBinding) {
List<String> classDirectAccessFields = serializedSchema.directAccessFields.get(currentClass);
if (classDirectAccessFields == null)
classDirectAccessFields = new ArrayList<String>();
classDirectAccessFields.add(fieldName);
serializedSchema.directAccessFields.put(currentClass, classDirectAccessFields);
}
if (f.getAnnotation(ODocumentInstance.class) != null)
// BOUND DOCUMENT ON IT
serializedSchema.boundDocumentFields.put(currentClass, f);
boolean idFound = false;
if (f.getAnnotation(OId.class) != null) {
// RECORD ID
serializedSchema.fieldIds.put(currentClass, f);
idFound = true;
} else // JPA 1+ AVAILABLE?
if (OObjectSerializerHelper.jpaIdClass != null && f.getAnnotation(OObjectSerializerHelper.jpaIdClass) != null) {
// RECORD ID
serializedSchema.fieldIds.put(currentClass, f);
idFound = true;
}
if (idFound) {
// CHECK FOR TYPE
if (fieldType.isPrimitive())
OLogManager.instance().warn(OObjectSerializerHelper.class, "Field '%s' cannot be a literal to manage the Record Id", f.toString());
else if (!ORID.class.isAssignableFrom(fieldType) && fieldType != String.class && fieldType != Object.class && !Number.class.isAssignableFrom(fieldType))
OLogManager.instance().warn(OObjectSerializerHelper.class, "Field '%s' cannot be managed as type: %s", f.toString(), fieldType);
}
boolean vFound = false;
if (f.getAnnotation(OVersion.class) != null) {
// RECORD ID
serializedSchema.fieldVersions.put(currentClass, f);
vFound = true;
} else // JPA 1+ AVAILABLE?
if (OObjectSerializerHelper.jpaVersionClass != null && f.getAnnotation(OObjectSerializerHelper.jpaVersionClass) != null) {
// RECORD ID
serializedSchema.fieldVersions.put(currentClass, f);
vFound = true;
}
if (vFound) {
// CHECK FOR TYPE
if (fieldType.isPrimitive())
OLogManager.instance().warn(OObjectSerializerHelper.class, "Field '%s' cannot be a literal to manage the Version", f.toString());
else if (fieldType != String.class && fieldType != Object.class && !Number.class.isAssignableFrom(fieldType))
OLogManager.instance().warn(OObjectSerializerHelper.class, "Field '%s' cannot be managed as type: %s", f.toString(), fieldType);
}
// JPA 1+ AVAILABLE?
if (OObjectSerializerHelper.jpaEmbeddedClass != null && f.getAnnotation(OObjectSerializerHelper.jpaEmbeddedClass) != null) {
List<String> classEmbeddedFields = serializedSchema.embeddedFields.get(currentClass);
if (classEmbeddedFields == null)
classEmbeddedFields = new ArrayList<String>();
classEmbeddedFields.add(fieldName);
serializedSchema.embeddedFields.put(currentClass, classEmbeddedFields);
}
}
registerCallbacks(currentClass);
}
if (automaticSchemaGeneration && !currentClass.equals(Object.class) && !currentClass.equals(ODocument.class)) {
((OSchemaProxyObject) db.getDatabaseOwner().getMetadata().getSchema()).generateSchema(currentClass, db);
}
String iClassName = currentClass.getSimpleName();
currentClass = currentClass.getSuperclass();
if (currentClass == null || currentClass.equals(ODocument.class))
// POJO EXTENDS ODOCUMENT: SPECIAL CASE: AVOID TO CONSIDER
// ODOCUMENT FIELDS
currentClass = Object.class;
if (!currentClass.equals(Object.class)) {
OClass oSuperClass;
OClass currentOClass = oSchema.getClass(iClassName);
if (!oSchema.existsClass(currentClass.getSimpleName())) {
OSchema schema = oSchema;
if (Modifier.isAbstract(currentClass.getModifiers())) {
oSuperClass = schema.createAbstractClass(currentClass.getSimpleName());
} else {
oSuperClass = schema.createClass(currentClass.getSimpleName());
}
reloadSchema = true;
} else {
oSuperClass = oSchema.getClass(currentClass.getSimpleName());
}
if (!currentOClass.getSuperClasses().contains(oSuperClass)) {
currentOClass.setSuperClasses(Arrays.asList(oSuperClass));
reloadSchema = true;
}
}
}
if (reloadSchema) {
oSchema.save();
oSchema.reload();
}
}
Aggregations