use of javax.persistence.ManyToOne in project eweb4j-framework by laiweiwei.
the class InsertSqlCreator method create.
public Sql[] create(String condition) throws SqlCreateException {
Sql[] sqls = new Sql[ts.length];
for (int index = 0; index < ts.length; ++index) {
String table = null;
StringBuilder columnSB = new StringBuilder();
StringBuilder valueSB = new StringBuilder();
T t = ts[index];
Class<?> clazz = t.getClass();
String[] fields;
String[] columns;
String idColumn;
Object[] values = null;
sqls[index] = new Sql();
HashMap<String, Object> map = null;
if (Map.class.isAssignableFrom(clazz)) {
map = (HashMap<String, Object>) t;
table = String.valueOf(map.get("table"));
idColumn = String.valueOf(map.get("idColumn"));
if (idColumn == null)
idColumn = "id";
fields = (String[]) map.get("columns");
columns = fields;
values = (Object[]) map.get("values");
} else {
table = ORMConfigBeanUtil.getTable(clazz, false);
idColumn = ORMConfigBeanUtil.getIdColumn(t.getClass());
fields = ORMConfigBeanUtil.getFields(clazz);
columns = ORMConfigBeanUtil.getColumns(clazz);
}
ReflectUtil ru = new ReflectUtil(t);
for (int i = 0; i < columns.length; i++) {
String column = columns[i];
Object value = null;
if (map != null && values != null) {
value = values[i];
} else {
String name = fields[i];
Method getter = ru.getGetter(name);
if (getter == null)
continue;
Object _value = null;
try {
_value = getter.invoke(t);
if (_value == null)
continue;
if (ClassUtil.isPojo(_value.getClass())) {
Field f = ru.getField(name);
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) {
JoinColumn joinColAnn = getter.getAnnotation(JoinColumn.class);
if (joinColAnn == null)
joinColAnn = f.getAnnotation(JoinColumn.class);
if (joinColAnn != null && joinColAnn.referencedColumnName().trim().length() > 0) {
String refCol = joinColAnn.referencedColumnName();
String refField = ORMConfigBeanUtil.getField(_value.getClass(), refCol);
ReflectUtil tarRu = new ReflectUtil(_value);
Method tarFKGetter = tarRu.getGetter(refField);
value = tarFKGetter.invoke(_value);
} else {
ReflectUtil tarRu = new ReflectUtil(_value);
String tarFKField = ORMConfigBeanUtil.getIdField(_value.getClass());
if (tarFKField != null) {
Method tarFKGetter = tarRu.getGetter(tarFKField);
value = tarFKGetter.invoke(_value);
}
}
}
if (value == null)
continue;
} else {
value = _value;
}
} catch (Exception e) {
throw new SqlCreateException(getter + " invoke exception " + e.toString(), e);
}
}
// id 字段不允许插入表中
if (idColumn != null && idColumn.equalsIgnoreCase(column))
continue;
if (columnSB.length() > 0)
columnSB.append(",");
columnSB.append(column);
if (valueSB.length() > 0)
valueSB.append(",");
// valueSB.append("'").append(value).append("'");
valueSB.append("?");
sqls[index].args.add(value);
}
String format = "INSERT INTO ${table}(${columns}) VALUES(${values}) ${condition} ;";
format = format.replace("${table}", table);
format = format.replace("${columns}", columnSB.toString());
format = format.replace("${values}", valueSB.toString());
if (condition != null)
format = format.replace("${condition}", " WHERE " + condition);
else
format = format.replace("${condition} ", "");
sqls[index].sql = format;
}
return sqls;
}
use of javax.persistence.ManyToOne in project eweb4j-framework by laiweiwei.
the class InsertSqlCreator method createByFieldsIsValues.
public Sql[] createByFieldsIsValues(String[][] fields, Object[][] values) throws SqlCreateException {
Sql[] sqls = new Sql[ts.length];
for (int i = 0; i < ts.length; ++i) {
T t = ts[i];
ReflectUtil ru = new ReflectUtil(t);
Class<?> clazz = t.getClass();
String table = ORMConfigBeanUtil.getTable(clazz, false);
StringBuilder columnSB = new StringBuilder();
StringBuilder valueSB = new StringBuilder();
sqls[i] = new Sql();
for (int j = 0; j < fields[i].length; ++j) {
String name = fields[i][j];
Object _value = null;
Object value = null;
if (values == null) {
Method getter = null;
try {
getter = ru.getGetter(name);
if (getter == null)
continue;
_value = getter.invoke(t);
if (_value == null)
continue;
if (ClassUtil.isPojo(_value.getClass())) {
Field f = ru.getField(fields[i][j]);
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) {
JoinColumn joinColAnn = getter.getAnnotation(JoinColumn.class);
if (joinColAnn == null)
joinColAnn = f.getAnnotation(JoinColumn.class);
if (joinColAnn != null && joinColAnn.referencedColumnName().trim().length() > 0) {
String refCol = joinColAnn.referencedColumnName();
String refField = ORMConfigBeanUtil.getField(_value.getClass(), refCol);
ReflectUtil tarRu = new ReflectUtil(_value);
Method tarFKGetter = tarRu.getGetter(refField);
value = tarFKGetter.invoke(_value);
} else {
ReflectUtil tarRu = new ReflectUtil(_value);
String tarFKField = ORMConfigBeanUtil.getIdField(_value.getClass());
if (tarFKField != null) {
Method tarFKGetter = tarRu.getGetter(tarFKField);
value = tarFKGetter.invoke(_value);
}
}
}
if (value == null)
continue;
} else {
value = _value;
}
} catch (Exception e) {
throw new SqlCreateException(getter + " invoke exception " + e.toString(), e);
}
} else {
value = values[i][j];
}
String column = ORMConfigBeanUtil.getColumn(clazz, name);
if (valueSB.length() > 0) {
columnSB.append(",");
valueSB.append(",");
}
columnSB.append(column);
// valueSB.append("'").append(value).append("'");
valueSB.append("?");
sqls[i].args.add(value);
}
sqls[i].sql = String.format("INSERT INTO %s(%s) VALUES(%s) ;", table, columnSB.toString(), valueSB.toString());
}
return sqls;
}
use of javax.persistence.ManyToOne in project eweb4j-framework by laiweiwei.
the class SelectSqlCreator method selectWhere.
/**
* 各种条件查询
*
* @param fields
* 构成条件的属性名数组(填写的应该是对象属性名,不是数据库字段名)
* @param values
* 构成条件的字段值
* @param likeType
* 匹配类型 -1左匹配 0全匹配 1右匹配
* @param isLike
* 是否模糊查询
* @param orderField
* 对哪个字段进行排序
* @param oType
* 升序还是降序
* @return 字符串
* @param currentPage
* 第几页
* @param numPerPage
* 每页显示多少条
* @return
* @throws SqlCreateException
*/
public String selectWhere(String[] fields, String[] values, int likeType, boolean isLike, boolean isNot, boolean isOR, String orderField, int oType, int currentPage, int numPerPage) throws SqlCreateException {
String oper = " = ";
String connector = " AND ";
String left = " '";
String right = "' ";
if (isNot)
oper = "<>";
if (isLike) {
oper = " LIKE ";
left = " '%";
right = "%' ";
if (isNot)
oper = " NOT LIKE ";
switch(likeType) {
case LikeType.LEFT_LIKE:
left = " '";
break;
case LikeType.RIGHT_LIKE:
right = "' ";
break;
case LikeType.ALL_LIKE:
}
}
if (isOR)
connector = " OR ";
String[] type = { oper, connector, left, right };
if (orderField == null) {
orderField = idColumn;
orderField = OrderColumnUtil.getOrderColumn(orderField, dbType);
} else
orderField = ORMConfigBeanUtil.getColumn(clazz, orderField);
StringBuilder condition = new StringBuilder();
String[] columns = ORMConfigBeanUtil.getColumns(clazz, fields);
for (int i = 0; i < columns.length; ++i) {
if (values != null)
if (condition.length() > 0)
condition.append(type[1]).append(columns[i]).append(" ").append(type[0]).append(type[2]).append(values[i]).append(type[3]);
else
condition.append(columns[i]).append(" ").append(type[0]).append(type[2]).append(values[i]).append(type[3]);
else {
ReflectUtil ru = new ReflectUtil(t);
Method getter = ru.getGetter(fields[i]);
if (getter == null)
continue;
try {
Object _value = getter.invoke(t);
if (_value == null)
continue;
Object value = null;
if (ClassUtil.isPojo(_value.getClass())) {
Field f = ru.getField(fields[i]);
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) {
JoinColumn joinColAnn = getter.getAnnotation(JoinColumn.class);
if (joinColAnn == null)
joinColAnn = f.getAnnotation(JoinColumn.class);
if (joinColAnn != null && joinColAnn.referencedColumnName().trim().length() > 0) {
String refCol = joinColAnn.referencedColumnName();
String refField = ORMConfigBeanUtil.getField(_value.getClass(), refCol);
ReflectUtil tarRu = new ReflectUtil(_value);
Method tarFKGetter = tarRu.getGetter(refField);
value = tarFKGetter.invoke(_value);
} else {
ReflectUtil tarRu = new ReflectUtil(_value);
String tarFKField = ORMConfigBeanUtil.getIdField(_value.getClass());
if (tarFKField != null) {
Method tarFKGetter = tarRu.getGetter(tarFKField);
value = tarFKGetter.invoke(_value);
}
}
}
if (value == null)
continue;
} else
value = _value;
if (condition.length() > 0)
condition.append(type[1]).append(columns[i]).append(" ").append(type[0]).append(type[2]).append(value).append(type[3]);
else
condition.append(columns[i]).append(" ").append(type[0]).append(type[2]).append(value).append(type[3]);
} catch (Exception e) {
e.printStackTrace();
throw new SqlCreateException(getter + " invoke exception " + e.toString());
}
}
}
String orderType = OrderType.ASC_ORDER == oType ? "ASC" : "DESC";
if (currentPage > 0 && numPerPage > 0)
return divPage(currentPage, numPerPage, orderField, oType, condition.toString());
else {
return String.format("SELECT %s FROM %s WHERE %s ORDER BY %s %s ;", selectAllColumn, table, condition.toString(), orderField, orderType);
}
}
use of javax.persistence.ManyToOne in project eweb4j-framework by laiweiwei.
the class UpdateSqlCreator method makeSQL.
private Sql makeSQL(T t) throws SqlCreateException {
Sql sql = new Sql();
Class<?> clazz = t.getClass();
String table;
String[] columns;
String[] fields;
Object[] values = null;
String idColumn;
String idField;
Object idValue = null;
HashMap<String, Object> map = null;
if (Map.class.isAssignableFrom(clazz)) {
map = (HashMap) t;
table = (String) map.get("table");
idColumn = (String) map.get("idColumn");
idField = idColumn;
idValue = map.get("idValue");
columns = (String[]) map.get("columns");
fields = columns;
values = (Object[]) map.get("values");
} else {
table = ORMConfigBeanUtil.getTable(clazz, false);
columns = ORMConfigBeanUtil.getColumns(clazz);
fields = ORMConfigBeanUtil.getFields(clazz);
idColumn = ORMConfigBeanUtil.getIdColumn(clazz);
idField = ORMConfigBeanUtil.getIdField(clazz);
}
StringBuilder valuesSb = new StringBuilder();
ReflectUtil ru = new ReflectUtil(t);
try {
if (map == null) {
Method idGetter = ru.getGetter(idField);
if (idGetter == null)
throw new SqlCreateException("can not find id getter");
idValue = idGetter.invoke(t);
}
for (int i = 0; i < columns.length; i++) {
String column = columns[i];
String field = fields[i];
Object value = null;
// id 字段不允许
if (idColumn != null && idColumn.equalsIgnoreCase(column))
continue;
if (map != null && values != null) {
value = values[i];
} else {
Method getter = ru.getGetter(field);
if (getter == null)
continue;
Object _value = getter.invoke(t);
if (_value == null)
continue;
if (ClassUtil.isPojo(_value.getClass())) {
Field f = ru.getField(field);
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) {
JoinColumn joinColAnn = getter.getAnnotation(JoinColumn.class);
if (joinColAnn == null)
joinColAnn = f.getAnnotation(JoinColumn.class);
if (joinColAnn != null && joinColAnn.referencedColumnName().trim().length() > 0) {
String refCol = joinColAnn.referencedColumnName();
String refField = ORMConfigBeanUtil.getField(_value.getClass(), refCol);
ReflectUtil tarRu = new ReflectUtil(_value);
Method tarFKGetter = tarRu.getGetter(refField);
value = tarFKGetter.invoke(_value);
} else {
ReflectUtil tarRu = new ReflectUtil(_value);
String tarFKField = ORMConfigBeanUtil.getIdField(_value.getClass());
if (tarFKField != null) {
Method tarFKGetter = tarRu.getGetter(tarFKField);
value = tarFKGetter.invoke(_value);
}
}
}
if (value == null)
continue;
} else
value = _value;
}
if (valuesSb.length() > 0)
valuesSb.append(",");
// valuesSb.append(column).append(" = '").append(value).append("'");
valuesSb.append(column).append(" = ? ");
sql.args.add(value);
}
} catch (Exception e) {
throw new SqlCreateException("" + e.toString(), e);
}
// String condition = new StringBuilder().append(idColumn).append(" = ").append("'").append(idValue).append("'").toString();
String condition = new StringBuilder().append(idColumn).append(" = ? ").toString();
sql.args.add(idValue);
sql.sql = String.format("UPDATE %s SET %s WHERE %s ;", table, valuesSb, condition);
return sql;
}
use of javax.persistence.ManyToOne 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);
}
}
}
}
Aggregations