#2156 - Using @OneToOne(targetEntity...) with Interface field results in BeanNotRegisteredException (#2160)

This commit is contained in:
Rob Bygrave
2021-02-12 16:30:28 +13:00
committed by GitHub
parent 536ea57369
commit d3a09b93c0
11 changed files with 142 additions and 73 deletions
@@ -176,4 +176,9 @@ public abstract class DeployBeanPropertyAssoc<T> extends DeployBeanProperty {
public void setFetchPreference(int fetchPreference) {
this.fetchPreference = fetchPreference;
}
@SuppressWarnings("unchecked")
public void setTargetType(Class<?> targetType) {
this.targetType = (Class<T>)targetType;
}
}
@@ -65,19 +65,6 @@ public class DeployBeanPropertyAssocMany<T> extends DeployBeanPropertyAssoc<T> {
this.manyType = manyType;
}
/**
* When generics is not used for manyType you can specify via annotations.
* <p>
* Really only expect this for Scala due to a Scala compiler bug at the moment.
* Otherwise I'd probably not bother support this.
* </p>
*/
@SuppressWarnings("unchecked")
public void setTargetType(Class<?> cls) {
this.targetType = (Class<T>) cls;
}
/**
* Return the many type.
*/
@@ -0,0 +1,39 @@
package io.ebeaninternal.server.deploy.parse;
import io.ebean.config.BeanNotRegisteredException;
import io.ebeaninternal.server.deploy.BeanDescriptorManager;
import io.ebeaninternal.server.deploy.BeanTable;
import io.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssoc;
abstract class AnnotationAssoc extends AnnotationParser {
final BeanDescriptorManager factory;
AnnotationAssoc(DeployBeanInfo<?> info, ReadAnnotationConfig readConfig, BeanDescriptorManager factory) {
super(info, readConfig);
this.factory = factory;
}
void setTargetType(Class<?> targetType, DeployBeanPropertyAssoc<?> prop) {
if (!targetType.equals(void.class)) {
prop.setTargetType(targetType);
}
}
void setBeanTable(DeployBeanPropertyAssoc<?> prop) {
BeanTable assoc = getBeanTable(prop);
if (assoc == null) {
throw new BeanNotRegisteredException(errorMsgMissingBeanTable(prop.getTargetType(), prop.getFullBeanName()));
}
prop.setBeanTable(assoc);
}
BeanTable getBeanTable(DeployBeanPropertyAssoc<?> prop) {
return factory.getBeanTable(prop.getTargetType());
}
private String errorMsgMissingBeanTable(Class<?> type, String from) {
return "Error with association to [" + type + "] from [" + from + "]. Is " + type + " registered? See https://ebean.io/docs/trouble-shooting#not-registered";
}
}
@@ -44,16 +44,10 @@ import static io.ebean.util.StringHelper.isNull;
/**
* Read the deployment annotation for Assoc Many beans.
*/
class AnnotationAssocManys extends AnnotationParser {
class AnnotationAssocManys extends AnnotationAssoc {
private final BeanDescriptorManager factory;
/**
* Create with the DeployInfo.
*/
AnnotationAssocManys(DeployBeanInfo<?> info, ReadAnnotationConfig readConfig, BeanDescriptorManager factory) {
super(info, readConfig);
this.factory = factory;
super(info, readConfig, factory);
}
/**
@@ -435,11 +429,6 @@ class AnnotationAssocManys extends AnnotationParser {
prop.setInverseJoin(inverseDest);
}
private String errorMsgMissingBeanTable(Class<?> type, String from) {
return "Error with association to [" + type + "] from [" + from + "]. Is " + type + " registered? See https://ebean.io/docs/trouble-shooting#not-registered";
}
private void readToMany(ManyToMany propAnn, DeployBeanPropertyAssocMany<?> manyProp) {
manyProp.setMappedBy(propAnn.mappedBy());
@@ -462,20 +451,6 @@ class AnnotationAssocManys extends AnnotationParser {
manyProp.getTableJoin().setType(SqlJoinType.OUTER);
}
private void setTargetType(Class<?> targetType, DeployBeanPropertyAssocMany<?> prop) {
if (!targetType.equals(void.class)) {
prop.setTargetType(targetType);
}
}
private void setBeanTable(DeployBeanPropertyAssocMany<?> manyProp) {
BeanTable assoc = factory.getBeanTable(manyProp.getTargetType());
if (assoc == null) {
throw new BeanNotRegisteredException(errorMsgMissingBeanTable(manyProp.getTargetType(), manyProp.getFullBeanName()));
}
manyProp.setBeanTable(assoc);
}
private String getM2MJoinTableName(BeanTable lhsTable, BeanTable rhsTable) {
TableName lhs = new TableName(lhsTable.getBaseTable());
@@ -33,18 +33,15 @@ import javax.validation.constraints.NotNull;
/**
* Read the deployment annotations for Associated One beans.
*/
public class AnnotationAssocOnes extends AnnotationParser {
public class AnnotationAssocOnes extends AnnotationAssoc {
private static final Logger log = LoggerFactory.getLogger(AnnotationAssocOnes.class);
private final BeanDescriptorManager factory;
/**
* Create with the deploy Info.
*/
AnnotationAssocOnes(DeployBeanInfo<?> info, ReadAnnotationConfig readConfig, BeanDescriptorManager factory) {
super(info, readConfig);
this.factory = factory;
super(info, readConfig, factory);
}
/**
@@ -191,25 +188,11 @@ public class AnnotationAssocOnes extends AnnotationParser {
}
}
private String errorMsgMissingBeanTable(Class<?> type, String from) {
return "Error with association to [" + type + "] from [" + from + "]. Is " + type + " registered? Does it have the @Entity annotation? See https://ebean.io/docs/trouble-shooting#not-registered";
}
private BeanTable beanTable(DeployBeanPropertyAssoc<?> prop) {
BeanTable assoc = factory.getBeanTable(prop.getPropertyType());
if (assoc == null) {
throw new BeanNotRegisteredException(errorMsgMissingBeanTable(prop.getPropertyType(), prop.getFullBeanName()));
}
return assoc;
}
private void readManyToOne(ManyToOne propAnn, DeployBeanProperty prop) {
DeployBeanPropertyAssocOne<?> beanProp = (DeployBeanPropertyAssocOne<?>) prop;
private void readManyToOne(ManyToOne propAnn, DeployBeanPropertyAssocOne<?> beanProp) {
setCascadeTypes(propAnn.cascade(), beanProp.getCascadeInfo());
beanProp.setBeanTable(beanTable(beanProp));
setTargetType(propAnn.targetEntity(), beanProp);
setBeanTable(beanProp);
beanProp.setDbInsertable(true);
beanProp.setDbUpdateable(true);
beanProp.setNullable(propAnn.optional());
@@ -232,7 +215,8 @@ public class AnnotationAssocOnes extends AnnotationParser {
}
setCascadeTypes(propAnn.cascade(), prop.getCascadeInfo());
prop.setBeanTable(beanTable(prop));
setTargetType(propAnn.targetEntity(), prop);
setBeanTable(prop);
}
private boolean readOrphanRemoval(OneToOne property) {
@@ -261,7 +245,7 @@ public class AnnotationAssocOnes extends AnnotationParser {
BeanTable baseBeanTable = factory.getBeanTable(info.getDescriptor().getBeanType());
String localPrimaryKey = baseBeanTable.getIdColumn();
String foreignColumn = beanTable(prop).getIdColumn();
String foreignColumn = getBeanTable(prop).getIdColumn();
prop.getTableJoin().addJoinColumn(new DeployTableJoinColumn(localPrimaryKey, foreignColumn, false, false));
}
@@ -145,14 +145,6 @@ public class DeployCreateProperties {
private DeployBeanProperty createProp(DeployBeanDescriptor<?> desc, Field field) {
Class<?> propertyType = field.getType();
ManyToOne manyToOne = AnnotationUtil.get(field, ManyToOne.class);
if (manyToOne != null) {
Class<?> tt = manyToOne.targetEntity();
if (!tt.equals(void.class)) {
propertyType = tt;
}
}
if (isSpecialScalarType(field)) {
return new DeployBeanProperty(desc, propertyType, field.getGenericType());
}