Java tutorial
/* * Copyright 2015 JAXIO http://www.jaxio.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.jaxio.celerio.model.support.jpa; import com.jaxio.celerio.configuration.database.Table; import com.jaxio.celerio.configuration.entity.CacheConfig; import com.jaxio.celerio.configuration.entity.CacheConfigGetter; import com.jaxio.celerio.configuration.entity.ColumnConfig; import com.jaxio.celerio.model.Attribute; import com.jaxio.celerio.model.Unique; import com.jaxio.celerio.model.unique.CompositeUnique; import com.jaxio.celerio.spi.support.AbstractEntitySpi; import com.jaxio.celerio.util.AnnotationBuilder; import com.jaxio.celerio.util.AttributeBuilder; import org.apache.commons.lang.StringUtils; import org.springframework.util.Assert; import java.util.List; import java.util.Set; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Sets.newHashSet; import static com.jaxio.celerio.configuration.database.support.SqlUtil.escapeSql; import static javax.persistence.InheritanceType.JOINED; import static javax.persistence.InheritanceType.SINGLE_TABLE; import static org.apache.commons.lang.StringUtils.isNotBlank; /** * Helper to write non trivial JPA annotations that may be applied to the generated entity class. * An annotation is considered non trivial when generating it would require an unreasonable * amount of velocity code in the template. */ public class JpaEntity extends AbstractEntitySpi { @Override public String velocityVar() { return "jpa"; } @Override public Object getTarget() { return this; } public List<String> getAnnotations() { AnnotationBuilder ab = new AnnotationBuilder(); ab.add(getEntityAnnotation()); ab.add(getHibernateCacheAnnotation()); // TODO: move to cache entity spi ? ab.add(getTableAnnotation()); ab.add(getInheritanceAnnotations()); ab.add(getDiscriminatorColumnAnnotation()); ab.add(getDiscriminatorValueAnnotation()); ab.add(getSecondaryTableAnnotations()); ab.add(getPrimaryKeyJoinColumnAnnotation()); ab.add(getAttributeOverrideAnnotation()); return ab.getAnnotations(); } public String getAttributeOverrideAnnotation() { if (entity.isRoot() || !entity.hasParent() || !entity.getParent().is(JOINED)) { return ""; } List<String> attributesOverrides = newArrayList(); AttributeBuilder attributeBuilder = new AttributeBuilder(); for (Attribute attribute : entity.getAttributes().getList()) { for (Attribute upAttribute : entity.getAttributes().getFlatAbove().getList()) { if (attribute.getColumnName().equalsIgnoreCase(upAttribute.getColumnName())) { addImport("javax.persistence.AttributeOverride"); String attributeOverride = "@AttributeOverride(name = \"" + attribute.getVar() + "\", column = @Column(name=\"" + attribute.getColumnNameEscaped() + "\"))"; attributesOverrides.add(attributeOverride); attributeBuilder.add(attributeOverride); } } } if (attributesOverrides.size() == 0) { return ""; } else if (attributesOverrides.size() == 1) { return appendComment(attributesOverrides.iterator().next()); } else { addImport("javax.persistence.AttributeOverrides"); return appendComment("@AttributeOverrides({" + attributeBuilder.getAttributes() + "})"); } } public String getPrimaryKeyJoinColumnAnnotation() { if (entity.isRoot() || !entity.hasInheritance() || !entity.getParent().is(JOINED)) { return ""; } Table rootTable = entity.getConfig().getMetadata().getTableByName(entity.getRoot().getTableName()); Table entityTable = entity.getConfig().getMetadata().getTableByName(entity.getTableName()); Assert.isTrue(rootTable.getPrimaryKeys().size() == 1, "Composite PK are not supported with JOIN inheritance strategy"); Assert.isTrue(entityTable.getPrimaryKeys().size() == 1, "Composite PK are not supported with JOIN inheritance strategy"); String rootPkColumnName = rootTable.getPrimaryKeys().iterator().next(); String entityPkColumnName = entityTable.getPrimaryKeys().iterator().next(); if (!entityPkColumnName.equalsIgnoreCase(rootPkColumnName)) { return appendComment(getPrimaryKeyJoinColumnAnnotation(entityPkColumnName)); } return ""; } public String getSecondaryTableAnnotations() { Set<Table> secondaryTables = getSecondaryTables(); if (secondaryTables.size() == 0) { return ""; } else if (secondaryTables.size() == 1) { return appendComment(getSecondaryTableAnnotation(secondaryTables.iterator().next().getName())); } else { addImport("javax.persistence.SecondaryTables"); StringBuilder sb = new StringBuilder("@SecondaryTables({"); boolean first = true; for (Table secondaryTable : secondaryTables) { if (first) { first = false; } else { sb.append(", "); } sb.append(getSecondaryTableAnnotation(secondaryTable.getName())); } sb.append("})"); return appendComment(sb.toString()); } } public String getDiscriminatorValueAnnotation() { if (!(entity.hasInheritance() && entity.getInheritance().hasDiscriminatorValue() && entity.is(SINGLE_TABLE))) { return ""; } addImport("javax.persistence.DiscriminatorValue"); return appendComment("@DiscriminatorValue(\"" + entity.getInheritance().getDiscriminatorValue() + "\")"); } public String getInheritanceAnnotations() { if (!(entity.hasInheritance() && entity.isRoot())) { return ""; } addImport("javax.persistence.Inheritance"); if (entity.is(SINGLE_TABLE)) { return appendComment("@Inheritance"); } else { addImport("javax.persistence.InheritanceType"); return appendComment( "@Inheritance(strategy = InheritanceType." + entity.getInheritance().getStrategy() + ")"); } } public String getDiscriminatorColumnAnnotation() { if (!(entity.hasInheritance() && entity.isRoot())) { return ""; } if (entity.getInheritance().hasDiscriminatorColumn()) { addImport("javax.persistence.DiscriminatorColumn"); return appendComment( "@DiscriminatorColumn(name = \"" + entity.getInheritance().getDiscriminatorColumn() + "\")"); } return ""; } private Set<Table> getSecondaryTables() { Set<Table> result = newHashSet(); for (ColumnConfig cc : entity.getEntityConfig().getColumnConfigs()) { // skip ignored attributes if (cc.hasTrueIgnore()) { continue; } // skip same table if (entity.getTableName().equalsIgnoreCase(cc.getTableName())) { continue; } // keep different ones Table secondaryTable = entity.getConfig().getMetadata().getTableByName(cc.getTableName()); result.add(secondaryTable); } return result; } private String getSecondaryTableAnnotation(String secondaryTableName) { Table table = entity.getConfig().getMetadata().getTableByName(entity.getTableName()); Table secondaryTable = entity.getConfig().getMetadata().getTableByName(secondaryTableName); Assert.isTrue(table.getPrimaryKeys().size() == 1, "The table '" + table.getName() + "' is expected to have a one-column primary key. " + "It has instead " + table.getPrimaryKeys().size()); Assert.isTrue(secondaryTable.getPrimaryKeys().size() == 1, "The secondary table '" + secondaryTable.getName() + "' is expected to have a one-column primary key. " + "It has instead " + secondaryTable.getPrimaryKeys().size()); String pkColumnName = table.getPrimaryKeys().iterator().next(); String secondaryPkColumnName = secondaryTable.getPrimaryKeys().iterator().next(); addImport("javax.persistence.SecondaryTable"); if (pkColumnName.equalsIgnoreCase(secondaryPkColumnName)) { return "@SecondaryTable(name = \"" + secondaryTable.getNameEscaped() + "\")"; } else { return "@SecondaryTable(name = \"" + secondaryTable.getNameEscaped() + "\", " + "pkJoinColumns = " + getPrimaryKeyJoinColumnAnnotation(secondaryPkColumnName) + ")"; } } private String getPrimaryKeyJoinColumnAnnotation(String pkColumnName) { addImport("javax.persistence.PrimaryKeyJoinColumn"); return "@PrimaryKeyJoinColumn(name = \"" + escapeSql(pkColumnName) + "\")"; } public String getSelectAllNamedQuery() { return entity.getModel().getType() + ".selectAll"; } public String getSelectAllNativeNamedQuery() { return entity.getModel().getType() + ".selectAll.native"; } public String getHibernateCacheAnnotation() { if (!entity.isRoot()) { return ""; } String cacheAnnotation = JpaConfigHelper.getCacheAnnotation(this, // entity.getEntityConfig(), // new CacheConfigGetter() { @Override public CacheConfig getCacheConfig() { return entity.getConfig().getCelerio().getConfiguration().getDefaultEntityCacheConfig(); } }); return appendComment(cacheAnnotation); } public String getEntityAnnotation() { addImport("javax.persistence.Entity"); return appendComment("@Entity"); } public String getTableAnnotation() { if (entity.isRoot() || (entity.hasInheritance() && entity.getParent().is(JOINED))) { StringBuffer annotation = new StringBuffer(""); appendAttribute(annotation, getName()); appendAttribute(annotation, getUniqueConstraints()); addImport("javax.persistence.Table"); return appendComment("@Table(" + annotation + ")"); } return ""; } private String getName() { return "name = \"" + escapeSql(entity.getTableName()) + "\""; } private String getUniqueConstraints() { List<String> constraints = getTableUniqueConstraints(); if (constraints.isEmpty()) { return ""; } else { String constraintsAsString = "uniqueConstraints = {"; boolean first = true; for (String constraint : constraints) { if (!first) { constraintsAsString += ", "; } else { first = false; } constraintsAsString += constraint; } constraintsAsString += "}"; return constraintsAsString; } } private List<String> getTableUniqueConstraints() { List<String> result = newArrayList(); for (Unique unique : entity.getCompositeUniques().getList()) { result.add(buildConstraint((CompositeUnique) unique)); } return result; } private String buildConstraint(CompositeUnique compositeUnique) { addImport("javax.persistence.UniqueConstraint"); String ret = "@UniqueConstraint("; if (StringUtils.isNotBlank(compositeUnique.getName())) { ret += "name=\"" + compositeUnique.getName() + "\", "; } ret += "columnNames = {"; boolean first = true; for (Attribute uniqueAttribute : compositeUnique.getAttributes()) { if (!first) { ret += ", "; } else { first = false; } ret += "\"" + escapeSql(uniqueAttribute.getColumnName()) + "\""; } ret += "})"; return ret; } private void appendAttribute(StringBuffer ret, String attribute) { if (isNotBlank(attribute)) { if (ret.length() > 0) { ret.append(", "); } ret.append(attribute); } } }