use of javax.persistence.ManyToMany in project eweb4j-framework by laiweiwei.
the class DAOImpl method queryBySql.
public <T> Collection<T> queryBySql(final String sql) {
Class<T> mappingCls = null;
if (this.targetEntity == null)
mappingCls = (Class<T>) this.clazz;
else
mappingCls = (Class<T>) this.targetEntity;
List<T> result = null;
try {
if (Map.class.isAssignableFrom(mappingCls)) {
Connection con = ds.getConnection();
if (args != null && args.size() > 0) {
result = (List<T>) JdbcUtil.getListWithArgs(con, mappingCls, sql, args.toArray(new Object[] {}));
} else {
result = (List<T>) JdbcUtil.getList(con, mappingCls, sql);
}
} else {
if (args != null && args.size() > 0) {
result = (List<T>) DAOFactory.getSelectDAO(dsName).selectBySQL(mappingCls, sql, args.toArray(new Object[] {}));
} else {
result = (List<T>) DAOFactory.getSelectDAO(dsName).selectBySQL(mappingCls, sql);
}
}
//this.clear();
if (result != null && result.size() > 0) {
for (T t : result) {
// ToOne relation class cascade select
ReflectUtil ru = new ReflectUtil(t);
for (Field field : ru.getFields()) {
String f = field.getName();
OneToOne o2o = field.getAnnotation(OneToOne.class);
ManyToOne m2o = field.getAnnotation(ManyToOne.class);
OneToMany o2m = field.getAnnotation(OneToMany.class);
ManyToMany m2m = field.getAnnotation(ManyToMany.class);
FetchType fetchType = null;
boolean is2One = false;
if (o2o != null) {
fetchType = o2o.fetch();
is2One = true;
}
if (m2o != null) {
fetchType = m2o.fetch();
is2One = true;
}
if (o2m != null) {
fetchType = o2m.fetch();
}
if (m2m != null) {
fetchType = m2m.fetch();
}
if (fetchType == null)
continue;
String beanId = field.getType().getName();
if (!is2One)
beanId = ClassUtil.getGenericType(field).getName();
boolean isEntity = ORMConfigBeanCache.containsKey(beanId);
if (!isEntity)
continue;
if (unFetch.contains(f))
continue;
if (fetch.contains(f)) {
log.debug("cascade select -> " + t.getClass().getName() + "." + f);
DAOFactory.getCascadeDAO(dsName).select(t, f);
continue;
}
if (FetchType.LAZY.equals(fetchType))
continue;
log.debug("cascade select -> " + t.getClass().getName() + "." + f);
DAOFactory.getCascadeDAO(dsName).select(t, f);
}
}
}
return result;
} catch (Exception e) {
log.error("sql-->" + sql, e);
throw new DAOException(sql + " execute exception", e);
}
}
use of javax.persistence.ManyToMany in project eweb4j-framework by laiweiwei.
the class Model2Table method generateOne.
public static String generateOne(final Class<?> entityClass, final boolean isDrop, boolean isCreateFile) {
StringBuilder sql = new StringBuilder();
StringBuilder manyMany = new StringBuilder();
final ORMConfigBean ocb = ORMConfigBeanCache.get(entityClass.getName());
final String table = ocb.getTable();
List<Property> properties = ocb.getProperty();
StringBuilder sb = new StringBuilder();
StringBuilder fkSb = new StringBuilder();
final String fk = ", \n\tKEY %s (%s), \n\tCONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)";
StringBuilder pkSb = new StringBuilder();
final String pk = ", \n\tPRIMARY KEY (%s)";
StringBuilder uniqueSb = new StringBuilder();
String unique = ", \n\tUNIQUE KEY %s (%s)";
final String idCol = ORMConfigBeanUtil.getIdColumn(properties);
for (Property p : properties) {
if (sb.length() > 0)
sb.append(", \n");
String col = p.getColumn();
String type = p.getType();
String size = null;
if (p.getSize().trim().length() > 0 && CommonUtil.isNumeric(p.getSize().trim()))
size = String.format(" (%s) ", p.getSize());
if ("1".equals(p.getUnique()) || "true".equalsIgnoreCase(p.getUnique()))
uniqueSb.append(String.format(unique, col, col));
String notNull = "";
if ("1".equals(p.getNotNull()) || "true".equalsIgnoreCase(p.getNotNull()))
notNull = " NOT NULL ";
if ("1".equals(p.getPk()) || "true".equalsIgnoreCase(p.getPk())) {
if (pkSb.length() > 0)
pkSb.append(",");
pkSb.append(col);
}
String auto = "";
if ("1".equals(p.getAutoIncrement()) || "true".equalsIgnoreCase(p.getAutoIncrement()))
auto = " AUTO_INCREMENT ";
if (PropType.ONE_ONE.equals(p.getType()) || PropType.MANY_ONE.equals(p.getType())) {
final String relTable = ORMConfigBeanUtil.getTable(p.getRelClass(), false);
if (p.getRelProperty() == null || p.getRelProperty().trim().length() == 0)
p.setRelProperty(ORMConfigBeanUtil.getIdField(p.getRelClass()));
final String relColumn = ORMConfigBeanUtil.getColumn(p.getRelClass(), p.getRelProperty());
fkSb.append(String.format(fk, col, col, table + "_" + col, col, relTable, relColumn));
}
sb.append("\t").append(col).append(" ").append(getType(type)).append(size == null ? "" : size).append(notNull).append(auto);
}
sb.append(uniqueSb.toString());
if (pkSb.length() > 0)
sb.append(String.format(pk, pkSb.toString()));
sb.append(fkSb.toString());
String _sql = String.format(create_table_script, table, sb.toString());
if (isDrop) {
_sql = String.format(drop_table_script, table) + _sql;
;
}
sql.append(_sql);
try {
ReflectUtil ru = new ReflectUtil(entityClass);
for (Field f : ru.getFields()) {
if (!ClassUtil.isListClass(f))
continue;
String name = f.getName();
Method getter = ru.getGetter(name);
if (getter == null)
continue;
ManyToMany mmAnn = getter.getAnnotation(ManyToMany.class);
if (mmAnn == null)
mmAnn = f.getAnnotation(ManyToMany.class);
if (mmAnn != null) {
JoinTable join = getter.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;
final String relTable = join.name();
final String relFrom = froms[0].name();
final String relTo = tos[0].name();
final Class<?> targetClass = ClassUtil.getGenericType(f);
StringBuilder manyManyField = new StringBuilder();
//handle the many to many
manyManyField.append("\tid ").append(getType("long")).append(" (20) NOT NULL AUTO_INCREMENT,");
manyManyField.append("\n\t").append(relFrom).append(" ").append(getType("long")).append(" (20) ,");
manyManyField.append("\n\t").append(relTo).append(" ").append(getType("long")).append(" (20) ,");
manyManyField.append("\n\t").append("PRIMARY KEY (id)");
String tarTable = ORMConfigBeanUtil.getTable(targetClass, false);
String tarIdCol = ORMConfigBeanUtil.getIdColumn(targetClass);
String fk1 = String.format(fk, relFrom, relFrom, relTable + "_" + relFrom, relFrom, table, idCol);
manyManyField.append(fk1);
String fk2 = String.format(fk, relTo, relTo, relTable + "_" + relTo, relTo, tarTable, tarIdCol);
manyManyField.append(fk2);
manyMany.append(String.format(create_table_script, relTable, relTable, manyManyField.toString()));
}
}
} catch (Exception e1) {
e1.printStackTrace();
}
sql.append(manyMany.toString());
String script = String.format("SET FOREIGN_KEY_CHECKS=0;\n%s", sql.toString());
if (!isCreateFile)
return script;
try {
ConfigBean cb = (ConfigBean) SingleBeanCache.get(ConfigBean.class.getName());
File file = new File(ConfigConstant.CONFIG_BASE_PATH() + cb.getOrm().getDdl().getDs() + "-create.sql");
FileWriter writer = new FileWriter(file);
writer.write(script);
writer.flush();
writer.close();
LogFactory.getORMLogger(Model2Table.class).debug("create models sql script file success -> " + file.getAbsoluteFile());
return script;
} catch (IOException e2) {
e2.printStackTrace();
return null;
}
}
use of javax.persistence.ManyToMany in project eweb4j-framework by laiweiwei.
the class Model2Table method generateAll.
public static String generateAll(final boolean isDrop, final boolean isCreateFile) {
StringBuilder sql = new StringBuilder();
StringBuilder manyMany = new StringBuilder();
for (Iterator<Entry<Object, ORMConfigBean>> it = ORMConfigBeanCache.entrySet().iterator(); it.hasNext(); ) {
final Entry<Object, ORMConfigBean> e = it.next();
final ORMConfigBean ocb = e.getValue();
final String table = ocb.getTable();
List<Property> properties = ocb.getProperty();
StringBuilder sb = new StringBuilder();
StringBuilder fkSb = new StringBuilder();
final String fk = ", \n\tKEY %s (%s), \n\tCONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)";
StringBuilder pkSb = new StringBuilder();
final String pk = ", \n\tPRIMARY KEY (%s)";
StringBuilder uniqueSb = new StringBuilder();
String unique = ", \n\tUNIQUE KEY %s (%s)";
final String idCol = ORMConfigBeanUtil.getIdColumn(properties);
for (Property p : properties) {
if (sb.length() > 0)
sb.append(", \n");
String col = p.getColumn();
String type = p.getType();
String size = null;
if (p.getSize().trim().length() > 0 && CommonUtil.isNumeric(p.getSize().trim()))
size = String.format(" (%s) ", p.getSize());
if ("1".equals(p.getUnique()) || "true".equalsIgnoreCase(p.getUnique()))
uniqueSb.append(String.format(unique, col, col));
String notNull = "";
if ("1".equals(p.getNotNull()) || "true".equalsIgnoreCase(p.getNotNull()))
notNull = " NOT NULL ";
if ("1".equals(p.getPk()) || "true".equalsIgnoreCase(p.getPk())) {
if (pkSb.length() > 0)
pkSb.append(",");
pkSb.append(col);
}
String auto = "";
if ("1".equals(p.getAutoIncrement()) || "true".equalsIgnoreCase(p.getAutoIncrement()))
auto = " AUTO_INCREMENT ";
if (PropType.ONE_ONE.equals(p.getType()) || PropType.MANY_ONE.equals(p.getType())) {
final String relTable = ORMConfigBeanUtil.getTable(p.getRelClass(), false);
if (p.getRelProperty() == null || p.getRelProperty().trim().length() == 0)
p.setRelProperty(ORMConfigBeanUtil.getIdField(p.getRelClass()));
final String relColumn = ORMConfigBeanUtil.getColumn(p.getRelClass(), p.getRelProperty());
fkSb.append(String.format(fk, col, col, table + "_" + col, col, relTable, relColumn));
}
sb.append("\t").append(col).append(" ").append(getType(type)).append(size == null ? "" : size).append(notNull).append(auto);
}
sb.append(uniqueSb.toString());
if (pkSb.length() > 0)
sb.append(String.format(pk, pkSb.toString()));
sb.append(fkSb.toString());
String _sql = String.format(create_table_script, table, sb.toString());
if (isDrop) {
_sql = String.format(drop_table_script, table) + _sql;
;
}
sql.append(_sql);
try {
Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass((String) e.getKey());
ReflectUtil ru = new ReflectUtil(clazz);
for (Field f : ru.getFields()) {
if (!ClassUtil.isListClass(f))
continue;
String name = f.getName();
Method getter = ru.getGetter(name);
if (getter == null)
continue;
ManyToMany mmAnn = getter.getAnnotation(ManyToMany.class);
if (mmAnn == null)
mmAnn = f.getAnnotation(ManyToMany.class);
if (mmAnn != null) {
JoinTable join = getter.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;
final String relTable = join.name();
final String relFrom = froms[0].name();
final String relTo = tos[0].name();
final Class<?> targetClass = ClassUtil.getGenericType(f);
StringBuilder manyManyField = new StringBuilder();
//handle the many to many
manyManyField.append("\tid ").append(getType("long")).append(" (20) NOT NULL AUTO_INCREMENT,");
manyManyField.append("\n\t").append(relFrom).append(" ").append(getType("long")).append(" (20) ,");
manyManyField.append("\n\t").append(relTo).append(" ").append(getType("long")).append(" (20) ,");
manyManyField.append("\n\t").append("PRIMARY KEY (id)");
String tarTable = ORMConfigBeanUtil.getTable(targetClass, false);
String tarIdCol = ORMConfigBeanUtil.getIdColumn(targetClass);
String fk1 = String.format(fk, relFrom, relFrom, relTable + "_" + relFrom, relFrom, table, idCol);
manyManyField.append(fk1);
String fk2 = String.format(fk, relTo, relTo, relTable + "_" + relTo, relTo, tarTable, tarIdCol);
manyManyField.append(fk2);
manyMany.append(String.format(create_table_script, relTable, relTable, manyManyField.toString()));
}
}
} catch (Exception e1) {
continue;
}
}
sql.append(manyMany.toString());
String script = String.format("SET FOREIGN_KEY_CHECKS=0;\n%s", sql.toString());
if (!isCreateFile)
return script;
try {
ConfigBean cb = (ConfigBean) SingleBeanCache.get(ConfigBean.class.getName());
File file = new File(ConfigConstant.CONFIG_BASE_PATH() + cb.getOrm().getDdl().getDs() + "-create.sql");
FileWriter writer = new FileWriter(file);
writer.write(script);
writer.flush();
writer.close();
LogFactory.getORMLogger(Model2Table.class).debug("create models sql script file success -> " + file.getAbsoluteFile());
return script;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
use of javax.persistence.ManyToMany in project hibernate-orm by hibernate.
the class AnnotationBinder method processElementAnnotations.
/*
* Process annotation of a particular property
*/
private static void processElementAnnotations(PropertyHolder propertyHolder, Nullability nullability, PropertyData inferredData, HashMap<String, IdentifierGeneratorDefinition> classGenerators, EntityBinder entityBinder, boolean isIdentifierMapper, boolean isComponentEmbedded, boolean inSecondPass, MetadataBuildingContext context, Map<XClass, InheritanceState> inheritanceStatePerClass) throws MappingException {
if (!propertyHolder.isComponent()) {
if (entityBinder.isPropertyDefinedInSuperHierarchy(inferredData.getPropertyName())) {
LOG.debugf("Skipping attribute [%s : %s] as it was already processed as part of super hierarchy", inferredData.getClassOrElementName(), inferredData.getPropertyName());
return;
}
}
/**
* inSecondPass can only be used to apply right away the second pass of a composite-element
* Because it's a value type, there is no bidirectional association, hence second pass
* ordering does not matter
*/
final boolean traceEnabled = LOG.isTraceEnabled();
if (traceEnabled) {
LOG.tracev("Processing annotations of {0}.{1}", propertyHolder.getEntityName(), inferredData.getPropertyName());
}
final XProperty property = inferredData.getProperty();
if (property.isAnnotationPresent(Parent.class)) {
if (propertyHolder.isComponent()) {
propertyHolder.setParentProperty(property.getName());
} else {
throw new AnnotationException("@Parent cannot be applied outside an embeddable object: " + BinderHelper.getPath(propertyHolder, inferredData));
}
return;
}
ColumnsBuilder columnsBuilder = new ColumnsBuilder(propertyHolder, nullability, property, inferredData, entityBinder, context).extractMetadata();
Ejb3Column[] columns = columnsBuilder.getColumns();
Ejb3JoinColumn[] joinColumns = columnsBuilder.getJoinColumns();
final XClass returnedClass = inferredData.getClassOrElement();
//prepare PropertyBinder
PropertyBinder propertyBinder = new PropertyBinder();
propertyBinder.setName(inferredData.getPropertyName());
propertyBinder.setReturnedClassName(inferredData.getTypeName());
propertyBinder.setAccessType(inferredData.getDefaultAccess());
propertyBinder.setHolder(propertyHolder);
propertyBinder.setProperty(property);
propertyBinder.setReturnedClass(inferredData.getPropertyClass());
propertyBinder.setBuildingContext(context);
if (isIdentifierMapper) {
propertyBinder.setInsertable(false);
propertyBinder.setUpdatable(false);
}
propertyBinder.setDeclaringClass(inferredData.getDeclaringClass());
propertyBinder.setEntityBinder(entityBinder);
propertyBinder.setInheritanceStatePerClass(inheritanceStatePerClass);
boolean isId = !entityBinder.isIgnoreIdAnnotations() && (property.isAnnotationPresent(Id.class) || property.isAnnotationPresent(EmbeddedId.class));
propertyBinder.setId(isId);
final LazyGroup lazyGroupAnnotation = property.getAnnotation(LazyGroup.class);
if (lazyGroupAnnotation != null) {
propertyBinder.setLazyGroup(lazyGroupAnnotation.value());
}
if (property.isAnnotationPresent(Version.class)) {
if (isIdentifierMapper) {
throw new AnnotationException("@IdClass class should not have @Version property");
}
if (!(propertyHolder.getPersistentClass() instanceof RootClass)) {
throw new AnnotationException("Unable to define/override @Version on a subclass: " + propertyHolder.getEntityName());
}
if (!propertyHolder.isEntity()) {
throw new AnnotationException("Unable to define @Version on an embedded class: " + propertyHolder.getEntityName());
}
if (traceEnabled) {
LOG.tracev("{0} is a version property", inferredData.getPropertyName());
}
RootClass rootClass = (RootClass) propertyHolder.getPersistentClass();
propertyBinder.setColumns(columns);
Property prop = propertyBinder.makePropertyValueAndBind();
setVersionInformation(property, propertyBinder);
rootClass.setVersion(prop);
//If version is on a mapped superclass, update the mapping
final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(inferredData.getDeclaringClass(), inheritanceStatePerClass, context);
if (superclass != null) {
superclass.setDeclaredVersion(prop);
} else {
//we know the property is on the actual entity
rootClass.setDeclaredVersion(prop);
}
SimpleValue simpleValue = (SimpleValue) prop.getValue();
simpleValue.setNullValue("undefined");
rootClass.setOptimisticLockStyle(OptimisticLockStyle.VERSION);
if (traceEnabled) {
LOG.tracev("Version name: {0}, unsavedValue: {1}", rootClass.getVersion().getName(), ((SimpleValue) rootClass.getVersion().getValue()).getNullValue());
}
} else {
final boolean forcePersist = property.isAnnotationPresent(MapsId.class) || property.isAnnotationPresent(Id.class);
if (property.isAnnotationPresent(ManyToOne.class)) {
ManyToOne ann = property.getAnnotation(ManyToOne.class);
//check validity
if (property.isAnnotationPresent(Column.class) || property.isAnnotationPresent(Columns.class)) {
throw new AnnotationException("@Column(s) not allowed on a @ManyToOne property: " + BinderHelper.getPath(propertyHolder, inferredData));
}
Cascade hibernateCascade = property.getAnnotation(Cascade.class);
NotFound notFound = property.getAnnotation(NotFound.class);
boolean ignoreNotFound = notFound != null && notFound.action().equals(NotFoundAction.IGNORE);
OnDelete onDeleteAnn = property.getAnnotation(OnDelete.class);
boolean onDeleteCascade = onDeleteAnn != null && OnDeleteAction.CASCADE.equals(onDeleteAnn.action());
JoinTable assocTable = propertyHolder.getJoinTable(property);
if (assocTable != null) {
Join join = propertyHolder.addJoin(assocTable, false);
for (Ejb3JoinColumn joinColumn : joinColumns) {
joinColumn.setExplicitTableName(join.getTable().getName());
}
}
final boolean mandatory = !ann.optional() || forcePersist;
bindManyToOne(getCascadeStrategy(ann.cascade(), hibernateCascade, false, forcePersist), joinColumns, !mandatory, ignoreNotFound, onDeleteCascade, ToOneBinder.getTargetEntity(inferredData, context), propertyHolder, inferredData, false, isIdentifierMapper, inSecondPass, propertyBinder, context);
} else if (property.isAnnotationPresent(OneToOne.class)) {
OneToOne ann = property.getAnnotation(OneToOne.class);
//check validity
if (property.isAnnotationPresent(Column.class) || property.isAnnotationPresent(Columns.class)) {
throw new AnnotationException("@Column(s) not allowed on a @OneToOne property: " + BinderHelper.getPath(propertyHolder, inferredData));
}
//FIXME support a proper PKJCs
boolean trueOneToOne = property.isAnnotationPresent(PrimaryKeyJoinColumn.class) || property.isAnnotationPresent(PrimaryKeyJoinColumns.class);
Cascade hibernateCascade = property.getAnnotation(Cascade.class);
NotFound notFound = property.getAnnotation(NotFound.class);
boolean ignoreNotFound = notFound != null && notFound.action().equals(NotFoundAction.IGNORE);
OnDelete onDeleteAnn = property.getAnnotation(OnDelete.class);
boolean onDeleteCascade = onDeleteAnn != null && OnDeleteAction.CASCADE.equals(onDeleteAnn.action());
JoinTable assocTable = propertyHolder.getJoinTable(property);
if (assocTable != null) {
Join join = propertyHolder.addJoin(assocTable, false);
for (Ejb3JoinColumn joinColumn : joinColumns) {
joinColumn.setExplicitTableName(join.getTable().getName());
}
}
//MapsId means the columns belong to the pk => not null
//@OneToOne with @PKJC can still be optional
final boolean mandatory = !ann.optional() || forcePersist;
bindOneToOne(getCascadeStrategy(ann.cascade(), hibernateCascade, ann.orphanRemoval(), forcePersist), joinColumns, !mandatory, getFetchMode(ann.fetch()), ignoreNotFound, onDeleteCascade, ToOneBinder.getTargetEntity(inferredData, context), propertyHolder, inferredData, ann.mappedBy(), trueOneToOne, isIdentifierMapper, inSecondPass, propertyBinder, context);
} else if (property.isAnnotationPresent(org.hibernate.annotations.Any.class)) {
//check validity
if (property.isAnnotationPresent(Column.class) || property.isAnnotationPresent(Columns.class)) {
throw new AnnotationException("@Column(s) not allowed on a @Any property: " + BinderHelper.getPath(propertyHolder, inferredData));
}
Cascade hibernateCascade = property.getAnnotation(Cascade.class);
OnDelete onDeleteAnn = property.getAnnotation(OnDelete.class);
boolean onDeleteCascade = onDeleteAnn != null && OnDeleteAction.CASCADE.equals(onDeleteAnn.action());
JoinTable assocTable = propertyHolder.getJoinTable(property);
if (assocTable != null) {
Join join = propertyHolder.addJoin(assocTable, false);
for (Ejb3JoinColumn joinColumn : joinColumns) {
joinColumn.setExplicitTableName(join.getTable().getName());
}
}
bindAny(getCascadeStrategy(null, hibernateCascade, false, forcePersist), //@Any has not cascade attribute
joinColumns, onDeleteCascade, nullability, propertyHolder, inferredData, entityBinder, isIdentifierMapper, context);
} else if (property.isAnnotationPresent(OneToMany.class) || property.isAnnotationPresent(ManyToMany.class) || property.isAnnotationPresent(ElementCollection.class) || property.isAnnotationPresent(ManyToAny.class)) {
OneToMany oneToManyAnn = property.getAnnotation(OneToMany.class);
ManyToMany manyToManyAnn = property.getAnnotation(ManyToMany.class);
ElementCollection elementCollectionAnn = property.getAnnotation(ElementCollection.class);
if ((oneToManyAnn != null || manyToManyAnn != null || elementCollectionAnn != null) && isToManyAssociationWithinEmbeddableCollection(propertyHolder)) {
throw new AnnotationException("@OneToMany, @ManyToMany or @ElementCollection cannot be used inside an @Embeddable that is also contained within an @ElementCollection: " + BinderHelper.getPath(propertyHolder, inferredData));
}
final IndexColumn indexColumn;
if (property.isAnnotationPresent(OrderColumn.class)) {
indexColumn = IndexColumn.buildColumnFromAnnotation(property.getAnnotation(OrderColumn.class), propertyHolder, inferredData, entityBinder.getSecondaryTables(), context);
if (property.isAnnotationPresent(ListIndexBase.class)) {
indexColumn.setBase((property.getAnnotation(ListIndexBase.class)).value());
}
} else {
//if @IndexColumn is not there, the generated IndexColumn is an implicit column and not used.
//so we can leave the legacy processing as the default
indexColumn = IndexColumn.buildColumnFromAnnotation(property.getAnnotation(org.hibernate.annotations.IndexColumn.class), propertyHolder, inferredData, context);
}
CollectionBinder collectionBinder = CollectionBinder.getCollectionBinder(propertyHolder.getEntityName(), property, !indexColumn.isImplicit(), property.isAnnotationPresent(MapKeyType.class), context);
collectionBinder.setIndexColumn(indexColumn);
collectionBinder.setMapKey(property.getAnnotation(MapKey.class));
collectionBinder.setPropertyName(inferredData.getPropertyName());
collectionBinder.setBatchSize(property.getAnnotation(BatchSize.class));
collectionBinder.setJpaOrderBy(property.getAnnotation(javax.persistence.OrderBy.class));
collectionBinder.setSqlOrderBy(property.getAnnotation(OrderBy.class));
collectionBinder.setSort(property.getAnnotation(Sort.class));
collectionBinder.setNaturalSort(property.getAnnotation(SortNatural.class));
collectionBinder.setComparatorSort(property.getAnnotation(SortComparator.class));
Cache cachAnn = property.getAnnotation(Cache.class);
collectionBinder.setCache(cachAnn);
collectionBinder.setPropertyHolder(propertyHolder);
Cascade hibernateCascade = property.getAnnotation(Cascade.class);
NotFound notFound = property.getAnnotation(NotFound.class);
boolean ignoreNotFound = notFound != null && notFound.action().equals(NotFoundAction.IGNORE);
collectionBinder.setIgnoreNotFound(ignoreNotFound);
collectionBinder.setCollectionType(inferredData.getProperty().getElementClass());
collectionBinder.setBuildingContext(context);
collectionBinder.setAccessType(inferredData.getDefaultAccess());
Ejb3Column[] elementColumns;
//do not use "element" if you are a JPA 2 @ElementCollection only for legacy Hibernate mappings
boolean isJPA2ForValueMapping = property.isAnnotationPresent(ElementCollection.class);
PropertyData virtualProperty = isJPA2ForValueMapping ? inferredData : new WrappedInferredData(inferredData, "element");
if (property.isAnnotationPresent(Column.class) || property.isAnnotationPresent(Formula.class)) {
Column ann = property.getAnnotation(Column.class);
Formula formulaAnn = property.getAnnotation(Formula.class);
elementColumns = Ejb3Column.buildColumnFromAnnotation(new Column[] { ann }, formulaAnn, nullability, propertyHolder, virtualProperty, entityBinder.getSecondaryTables(), context);
} else if (property.isAnnotationPresent(Columns.class)) {
Columns anns = property.getAnnotation(Columns.class);
elementColumns = Ejb3Column.buildColumnFromAnnotation(anns.columns(), null, nullability, propertyHolder, virtualProperty, entityBinder.getSecondaryTables(), context);
} else {
elementColumns = Ejb3Column.buildColumnFromAnnotation(null, null, nullability, propertyHolder, virtualProperty, entityBinder.getSecondaryTables(), context);
}
{
Column[] keyColumns = null;
//JPA 2 has priority and has different default column values, differenciate legacy from JPA 2
Boolean isJPA2 = null;
if (property.isAnnotationPresent(MapKeyColumn.class)) {
isJPA2 = Boolean.TRUE;
keyColumns = new Column[] { new MapKeyColumnDelegator(property.getAnnotation(MapKeyColumn.class)) };
}
//not explicitly legacy
if (isJPA2 == null) {
isJPA2 = Boolean.TRUE;
}
//nullify empty array
keyColumns = keyColumns != null && keyColumns.length > 0 ? keyColumns : null;
//"mapkey" is the legacy column name of the key column pre JPA 2
PropertyData mapKeyVirtualProperty = new WrappedInferredData(inferredData, "mapkey");
Ejb3Column[] mapColumns = Ejb3Column.buildColumnFromAnnotation(keyColumns, null, Nullability.FORCED_NOT_NULL, propertyHolder, isJPA2 ? inferredData : mapKeyVirtualProperty, isJPA2 ? "_KEY" : null, entityBinder.getSecondaryTables(), context);
collectionBinder.setMapKeyColumns(mapColumns);
}
{
JoinColumn[] joinKeyColumns = null;
//JPA 2 has priority and has different default column values, differenciate legacy from JPA 2
Boolean isJPA2 = null;
if (property.isAnnotationPresent(MapKeyJoinColumns.class)) {
isJPA2 = Boolean.TRUE;
final MapKeyJoinColumn[] mapKeyJoinColumns = property.getAnnotation(MapKeyJoinColumns.class).value();
joinKeyColumns = new JoinColumn[mapKeyJoinColumns.length];
int index = 0;
for (MapKeyJoinColumn joinColumn : mapKeyJoinColumns) {
joinKeyColumns[index] = new MapKeyJoinColumnDelegator(joinColumn);
index++;
}
if (property.isAnnotationPresent(MapKeyJoinColumn.class)) {
throw new AnnotationException("@MapKeyJoinColumn and @MapKeyJoinColumns used on the same property: " + BinderHelper.getPath(propertyHolder, inferredData));
}
} else if (property.isAnnotationPresent(MapKeyJoinColumn.class)) {
isJPA2 = Boolean.TRUE;
joinKeyColumns = new JoinColumn[] { new MapKeyJoinColumnDelegator(property.getAnnotation(MapKeyJoinColumn.class)) };
}
//not explicitly legacy
if (isJPA2 == null) {
isJPA2 = Boolean.TRUE;
}
PropertyData mapKeyVirtualProperty = new WrappedInferredData(inferredData, "mapkey");
Ejb3JoinColumn[] mapJoinColumns = Ejb3JoinColumn.buildJoinColumnsWithDefaultColumnSuffix(joinKeyColumns, null, entityBinder.getSecondaryTables(), propertyHolder, isJPA2 ? inferredData.getPropertyName() : mapKeyVirtualProperty.getPropertyName(), isJPA2 ? "_KEY" : null, context);
collectionBinder.setMapKeyManyToManyColumns(mapJoinColumns);
}
//potential element
collectionBinder.setEmbedded(property.isAnnotationPresent(Embedded.class));
collectionBinder.setElementColumns(elementColumns);
collectionBinder.setProperty(property);
//TODO enhance exception with @ManyToAny and @CollectionOfElements
if (oneToManyAnn != null && manyToManyAnn != null) {
throw new AnnotationException("@OneToMany and @ManyToMany on the same property is not allowed: " + propertyHolder.getEntityName() + "." + inferredData.getPropertyName());
}
String mappedBy = null;
if (oneToManyAnn != null) {
for (Ejb3JoinColumn column : joinColumns) {
if (column.isSecondary()) {
throw new NotYetImplementedException("Collections having FK in secondary table");
}
}
collectionBinder.setFkJoinColumns(joinColumns);
mappedBy = oneToManyAnn.mappedBy();
collectionBinder.setTargetEntity(context.getBuildingOptions().getReflectionManager().toXClass(oneToManyAnn.targetEntity()));
collectionBinder.setCascadeStrategy(getCascadeStrategy(oneToManyAnn.cascade(), hibernateCascade, oneToManyAnn.orphanRemoval(), false));
collectionBinder.setOneToMany(true);
} else if (elementCollectionAnn != null) {
for (Ejb3JoinColumn column : joinColumns) {
if (column.isSecondary()) {
throw new NotYetImplementedException("Collections having FK in secondary table");
}
}
collectionBinder.setFkJoinColumns(joinColumns);
mappedBy = "";
final Class<?> targetElement = elementCollectionAnn.targetClass();
collectionBinder.setTargetEntity(context.getBuildingOptions().getReflectionManager().toXClass(targetElement));
//collectionBinder.setCascadeStrategy( getCascadeStrategy( embeddedCollectionAnn.cascade(), hibernateCascade ) );
collectionBinder.setOneToMany(true);
} else if (manyToManyAnn != null) {
mappedBy = manyToManyAnn.mappedBy();
collectionBinder.setTargetEntity(context.getBuildingOptions().getReflectionManager().toXClass(manyToManyAnn.targetEntity()));
collectionBinder.setCascadeStrategy(getCascadeStrategy(manyToManyAnn.cascade(), hibernateCascade, false, false));
collectionBinder.setOneToMany(false);
} else if (property.isAnnotationPresent(ManyToAny.class)) {
mappedBy = "";
collectionBinder.setTargetEntity(context.getBuildingOptions().getReflectionManager().toXClass(void.class));
collectionBinder.setCascadeStrategy(getCascadeStrategy(null, hibernateCascade, false, false));
collectionBinder.setOneToMany(false);
}
collectionBinder.setMappedBy(mappedBy);
bindJoinedTableAssociation(property, context, entityBinder, collectionBinder, propertyHolder, inferredData, mappedBy);
OnDelete onDeleteAnn = property.getAnnotation(OnDelete.class);
boolean onDeleteCascade = onDeleteAnn != null && OnDeleteAction.CASCADE.equals(onDeleteAnn.action());
collectionBinder.setCascadeDeleteEnabled(onDeleteCascade);
if (isIdentifierMapper) {
collectionBinder.setInsertable(false);
collectionBinder.setUpdatable(false);
}
if (property.isAnnotationPresent(CollectionId.class)) {
//do not compute the generators unless necessary
HashMap<String, IdentifierGeneratorDefinition> localGenerators = (HashMap<String, IdentifierGeneratorDefinition>) classGenerators.clone();
localGenerators.putAll(buildLocalGenerators(property, context));
collectionBinder.setLocalGenerators(localGenerators);
}
collectionBinder.setInheritanceStatePerClass(inheritanceStatePerClass);
collectionBinder.setDeclaringClass(inferredData.getDeclaringClass());
collectionBinder.bind();
} else //Either a regular property or a basic @Id or @EmbeddedId while not ignoring id annotations
if (!isId || !entityBinder.isIgnoreIdAnnotations()) {
//define whether the type is a component or not
boolean isComponent = false;
//Overrides from @MapsId if needed
boolean isOverridden = false;
if (isId || propertyHolder.isOrWithinEmbeddedId() || propertyHolder.isInIdClass()) {
//the associated entity could be using an @IdClass making the overridden property a component
final PropertyData overridingProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId(isId, propertyHolder, property.getName(), context);
if (overridingProperty != null) {
isOverridden = true;
final InheritanceState state = inheritanceStatePerClass.get(overridingProperty.getClassOrElement());
if (state != null) {
isComponent = isComponent || state.hasIdClassOrEmbeddedId();
}
//Get the new column
columns = columnsBuilder.overrideColumnFromMapperOrMapsIdProperty(isId);
}
}
isComponent = isComponent || property.isAnnotationPresent(Embedded.class) || property.isAnnotationPresent(EmbeddedId.class) || returnedClass.isAnnotationPresent(Embeddable.class);
if (isComponent) {
String referencedEntityName = null;
if (isOverridden) {
final PropertyData mapsIdProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId(isId, propertyHolder, property.getName(), context);
referencedEntityName = mapsIdProperty.getClassOrElementName();
}
AccessType propertyAccessor = entityBinder.getPropertyAccessor(property);
propertyBinder = bindComponent(inferredData, propertyHolder, propertyAccessor, entityBinder, isIdentifierMapper, context, isComponentEmbedded, isId, inheritanceStatePerClass, referencedEntityName, isOverridden ? (Ejb3JoinColumn[]) columns : null);
} else {
//provide the basic property mapping
boolean optional = true;
boolean lazy = false;
if (property.isAnnotationPresent(Basic.class)) {
Basic ann = property.getAnnotation(Basic.class);
optional = ann.optional();
lazy = ann.fetch() == FetchType.LAZY;
}
//implicit type will check basic types and Serializable classes
if (isId || (!optional && nullability != Nullability.FORCED_NULL)) {
//force columns to not null
for (Ejb3Column col : columns) {
if (isId && col.isFormula()) {
throw new CannotForceNonNullableException(String.format(Locale.ROOT, "Identifier property [%s] cannot contain formula mapping [%s]", HCANNHelper.annotatedElementSignature(property), col.getFormulaString()));
}
col.forceNotNull();
}
}
propertyBinder.setLazy(lazy);
propertyBinder.setColumns(columns);
if (isOverridden) {
final PropertyData mapsIdProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId(isId, propertyHolder, property.getName(), context);
propertyBinder.setReferencedEntityName(mapsIdProperty.getClassOrElementName());
}
propertyBinder.makePropertyValueAndBind();
}
if (isOverridden) {
final PropertyData mapsIdProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId(isId, propertyHolder, property.getName(), context);
Map<String, IdentifierGeneratorDefinition> localGenerators = (HashMap<String, IdentifierGeneratorDefinition>) classGenerators.clone();
final IdentifierGeneratorDefinition.Builder foreignGeneratorBuilder = new IdentifierGeneratorDefinition.Builder();
foreignGeneratorBuilder.setName("Hibernate-local--foreign generator");
foreignGeneratorBuilder.setStrategy("foreign");
foreignGeneratorBuilder.addParam("property", mapsIdProperty.getPropertyName());
final IdentifierGeneratorDefinition foreignGenerator = foreignGeneratorBuilder.build();
localGenerators.put(foreignGenerator.getName(), foreignGenerator);
BinderHelper.makeIdGenerator((SimpleValue) propertyBinder.getValue(), foreignGenerator.getStrategy(), foreignGenerator.getName(), context, localGenerators);
}
if (isId) {
//components and regular basic types create SimpleValue objects
final SimpleValue value = (SimpleValue) propertyBinder.getValue();
if (!isOverridden) {
processId(propertyHolder, inferredData, value, classGenerators, isIdentifierMapper, context);
}
}
}
}
//init index
//process indexes afterQuery everything: in second pass, many to one has to be done beforeQuery indexes
Index index = property.getAnnotation(Index.class);
if (index != null) {
if (joinColumns != null) {
for (Ejb3Column column : joinColumns) {
column.addIndex(index, inSecondPass);
}
} else {
if (columns != null) {
for (Ejb3Column column : columns) {
column.addIndex(index, inSecondPass);
}
}
}
}
// Natural ID columns must reside in one single UniqueKey within the Table.
// For now, simply ensure consistent naming.
// TODO: AFAIK, there really isn't a reason for these UKs to be created
// on the secondPass. This whole area should go away...
NaturalId naturalIdAnn = property.getAnnotation(NaturalId.class);
if (naturalIdAnn != null) {
if (joinColumns != null) {
for (Ejb3Column column : joinColumns) {
String keyName = "UK_" + Constraint.hashedName(column.getTable().getName() + "_NaturalID");
column.addUniqueKey(keyName, inSecondPass);
}
} else {
for (Ejb3Column column : columns) {
String keyName = "UK_" + Constraint.hashedName(column.getTable().getName() + "_NaturalID");
column.addUniqueKey(keyName, inSecondPass);
}
}
}
}
use of javax.persistence.ManyToMany in project hibernate-orm by hibernate.
the class PersistentAttributesHelper method getTargetEntityClass.
public static CtClass getTargetEntityClass(CtClass managedCtClass, CtField persistentField) throws NotFoundException {
// get targetEntity defined in the annotation
try {
OneToOne oto = PersistentAttributesHelper.getAnnotation(persistentField, OneToOne.class);
OneToMany otm = PersistentAttributesHelper.getAnnotation(persistentField, OneToMany.class);
ManyToOne mto = PersistentAttributesHelper.getAnnotation(persistentField, ManyToOne.class);
ManyToMany mtm = PersistentAttributesHelper.getAnnotation(persistentField, ManyToMany.class);
Class<?> targetClass = null;
if (oto != null) {
targetClass = oto.targetEntity();
}
if (otm != null) {
targetClass = otm.targetEntity();
}
if (mto != null) {
targetClass = mto.targetEntity();
}
if (mtm != null) {
targetClass = mtm.targetEntity();
}
if (targetClass != null && targetClass != void.class) {
return managedCtClass.getClassPool().get(targetClass.getName());
}
} catch (NotFoundException ignore) {
}
// infer targetEntity from generic type signature
String inferredTypeName = inferTypeName(managedCtClass, persistentField.getName());
return inferredTypeName == null ? null : managedCtClass.getClassPool().get(inferredTypeName);
}
Aggregations