/* * Copyright 2011-2015 the original author or authors. * * 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.github.geequery.springdata.repository.support; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.persistence.metamodel.Metamodel; import javax.persistence.metamodel.SingularAttribute; import jef.database.DbUtils; import jef.database.IQueryableEntity; import jef.database.dialect.type.ColumnMapping; import jef.database.jpa.MetaProvider; import jef.database.meta.AbstractMetadata; import jef.database.meta.ITableMetadata; import org.springframework.beans.BeanWrapper; import org.springframework.data.repository.core.support.AbstractEntityInformation; import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper; import org.springframework.util.Assert; /** * Implementation of * {@link org.springframework.data.repository.core.EntityInformation} that uses * GeeQuery metamodel * * 由于标准JPA模型的复合主键处理方式一般为ID class,而本框架推荐使用多值,因此干脆统一所有的主键定义为Object[] * * @author Jiyi */ public class MetamodelInformation<T,ID extends Serializable> extends AbstractEntityInformation<T, ID> implements GQEntityInformation<T,ID> { private ITableMetadata metadata; private final SingularAttribute<? super T, ?> versionAttribute; private final String entityName; /** * Creates a new {@link MetamodelInformation} for the given domain class and * {@link Metamodel}. * * @param domainClass * must not be {@literal null}. * @param metamodel * must not be {@literal null}. */ public MetamodelInformation(Class<T> domainClass, MetaProvider metamodel) { super(domainClass); Assert.notNull(metamodel); AbstractMetadata type = metamodel.managedType(domainClass); if (type == null) { throw new IllegalArgumentException("The given domain class can not be found in the given Metamodel!"); } this.metadata= type; this.entityName = type.getName(); this.versionAttribute = null; } public ITableMetadata getMetadata() { return metadata; } /* * (non-Javadoc) * * @see * com.github.geequery.springdata.repository.support.JpaEntityInformationSupport * #getEntityName() */ @Override public String getEntityName() { return entityName; } /* * (non-Javadoc) * * @see * org.springframework.data.repository.core.EntityInformation#getId(java * .lang.Object) */ @SuppressWarnings("unchecked") public ID getId(T entity) { if(metadata.getPKFields().size()==1){ return (ID)DbUtils.getPKValueSafe((IQueryableEntity)entity).get(0); }else{ return (ID) DbUtils.getPKValueSafe((IQueryableEntity)entity); } } /* * (non-Javadoc) * * @see * org.springframework.data.repository.core.EntityInformation#getIdType() */ @SuppressWarnings("unchecked") public Class<ID> getIdType() { if(metadata.getPKFields().size()==1){ return (Class<ID>) metadata.getPKFields().get(0).getFieldType(); } return (Class)Object.class; } /* * (non-Javadoc) * * @see * com.github.geequery.springdata.repository.support.JpaEntityInformation * #getIdAttribute() */ public ColumnMapping getIdAttribute() { List<ColumnMapping> columns=metadata.getPKFields(); if(columns.size()!=1){ throw new UnsupportedOperationException(); } return columns.get(0); } /* * (non-Javadoc) * * @see * com.github.geequery.springdata.repository.support.JpaEntityInformation * #hasCompositeId() */ public boolean hasCompositeId() { return metadata.getPKFields().size()>1; } /* * (non-Javadoc) * * @see * #getIdAttributeNames() */ public Iterable<String> getIdAttributeNames() { List<ColumnMapping> columns=metadata.getPKFields(); List<String> result=new ArrayList<String>(columns.size()); for(ColumnMapping c:columns){ result.add(c.fieldName()); } return result; } /* * (non-Javadoc) * * @see * com.github.geequery.springdata.repository.support.JpaEntityInformation * #getCompositeIdAttributeValue(java.io.Serializable, java.lang.String) */ public Object getCompositeIdAttributeValue(Serializable id, String idAttribute) { Assert.isTrue(hasCompositeId()); return new DirectFieldAccessFallbackBeanWrapper(id).getPropertyValue(idAttribute); } /* * (non-Javadoc) * * @see * org.springframework.data.repository.core.support.AbstractEntityInformation * #isNew(java.lang.Object) */ @Override public boolean isNew(T entity) { if (versionAttribute == null || versionAttribute.getJavaType().isPrimitive()) { return super.isNew(entity); } BeanWrapper wrapper = new DirectFieldAccessFallbackBeanWrapper(entity); Object versionValue = wrapper.getPropertyValue(versionAttribute.getName()); return versionValue == null; } public boolean isComplexPK() { return this.metadata.getPKFields().size()>1; } }