Skip to content

Commit

Permalink
Fix for #173 - Ability to use a MappedSuperClass without being enhanc…
Browse files Browse the repository at this point in the history
…ed as long as it doesn't have persistent fields
  • Loading branch information
rbygrave committed Jul 19, 2014
1 parent 2dca1bd commit 0c4fc4e
Show file tree
Hide file tree
Showing 11 changed files with 164 additions and 60 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
<dependency>
<groupId>org.avaje.ebeanorm</groupId>
<artifactId>avaje-ebeanorm-agent</artifactId>
<version>4.1.2</version>
<version>4.1.5</version>
<scope>test</scope>
</dependency>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.avaje.ebeaninternal.server.deploy;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
Expand All @@ -11,7 +13,9 @@
import java.util.Map;
import java.util.Set;

import javax.persistence.MappedSuperclass;
import javax.persistence.PersistenceException;
import javax.persistence.Transient;
import javax.sql.DataSource;

import org.slf4j.Logger;
Expand Down Expand Up @@ -61,9 +65,7 @@
import com.avaje.ebeaninternal.server.lib.util.Dnode;
import com.avaje.ebeaninternal.server.reflect.BeanReflect;
import com.avaje.ebeaninternal.server.reflect.BeanReflectFactory;
import com.avaje.ebeaninternal.server.reflect.BeanReflectGetter;
import com.avaje.ebeaninternal.server.reflect.BeanReflectProperties;
import com.avaje.ebeaninternal.server.reflect.BeanReflectSetter;
import com.avaje.ebeaninternal.server.reflect.EnhanceBeanReflectFactory;
import com.avaje.ebeaninternal.server.type.TypeManager;

Expand Down Expand Up @@ -1154,12 +1156,8 @@ private void createByteCode(DeployBeanDescriptor<?> deploy) {
*/
private void setScalarType(DeployBeanDescriptor<?> deployDesc) {

Iterator<DeployBeanProperty> it = deployDesc.propertiesAll();
while (it.hasNext()) {
DeployBeanProperty prop = it.next();
if (prop instanceof DeployBeanPropertyAssoc<?>) {

} else {
for (DeployBeanProperty prop : deployDesc.propertiesAll()) {
if (prop instanceof DeployBeanPropertyAssoc<?> == false) {
deployUtil.setScalarType(prop);
}
}
Expand Down Expand Up @@ -1313,28 +1311,37 @@ private void setBeanReflect(DeployBeanDescriptor<?> desc) {
desc.setBeanReflect(beanReflect);
desc.setProperties(reflectProps.getProperties());

Iterator<DeployBeanProperty> it = desc.propertiesAll();
while (it.hasNext()) {
DeployBeanProperty prop = it.next();
for (DeployBeanProperty prop : desc.propertiesAll()) {
String propName = prop.getName();

Integer pos = reflectProps.getPropertyIndex(propName);
if (pos == null) {
throw new IllegalStateException("Property "+propName+" not found in "+reflectProps);
if (isPersistentField(prop)) {
throw new IllegalStateException("Property "+propName+" not found in "+reflectProps);
}

} else {
int propertyIndex = pos.intValue();
prop.setPropertyIndex(propertyIndex);
prop.setGetter(beanReflect.getGetter(propName, propertyIndex));
prop.setSetter(beanReflect.getSetter(propName, propertyIndex));
}
}
}

BeanReflectGetter getter = beanReflect.getGetter(propName, pos.intValue());
BeanReflectSetter setter = beanReflect.getSetter(propName, pos.intValue());
prop.setGetter(getter);
prop.setSetter(setter);
prop.setPropertyIndex(pos.intValue());

if (getter == null) {
String m = "BeanReflectGetter for " + prop.getFullBeanName() + " was not found?";
throw new RuntimeException(m);

}
/**
* Return true if this is a persistent field (not transient or static).
*/
private boolean isPersistentField(DeployBeanProperty prop) {

Field field = prop.getField();
int modifiers = field.getModifiers();
if (Modifier.isStatic(modifiers) || Modifier.isTransient(modifiers)) {
return false;
}
if (field.isAnnotationPresent(Transient.class)) {
return false;
}
return true;
}

/**
Expand Down Expand Up @@ -1408,6 +1415,7 @@ private void setEntityBeanClass(DeployBeanDescriptor<?> desc) {
* enhanced or all dynamically subclassed).
*/
private void checkInheritedClasses(Class<?> beanClass) {

Class<?> superclass = beanClass.getSuperclass();
if (Object.class.equals(superclass)) {
// we got to the top of the inheritance
Expand All @@ -1418,14 +1426,40 @@ private void checkInheritedClasses(Class<?> beanClass) {
return;
}
if (!EntityBean.class.isAssignableFrom(superclass)) {
if (isMappedSuperWithNoProperties(superclass)) {
// ok to stop and treat just the same as Object.class
return;
}
throw new IllegalStateException("Super type "+superclass+" is not enhanced?");
}


// recursively continue up the inheritance hierarchy
checkInheritedClasses(superclass);
}

/**
* Return true if this is a MappedSuperclass bean with no persistent properties.
* If so it is ok for it not to be enhanced.
*/
private boolean isMappedSuperWithNoProperties(Class<?> beanClass) {

MappedSuperclass annotation = beanClass.getAnnotation(MappedSuperclass.class);
if (annotation == null) {
return false;
}
Field[] fields = beanClass.getDeclaredFields();
for (Field field : fields) {
if (Modifier.isStatic(field.getModifiers()) || Modifier.isTransient(field.getModifiers())) {
// ignore this field
} else if (field.isAnnotationPresent(Transient.class)) {
// ignore this field
} else {
return false;
}
}
return true;
}

/**
* Comparator to sort the BeanDescriptors by name.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -707,10 +707,10 @@ public List<DeployTableJoin> getTableJoins() {
}

/**
* Return an Iterator of all BeanProperty.
* Return a collection of all BeanProperty deployment information.
*/
public Iterator<DeployBeanProperty> propertiesAll() {
return propMap.values().iterator();
public Collection<DeployBeanProperty> propertiesAll() {
return propMap.values();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.avaje.ebeaninternal.server.deploy.meta;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;

Expand Down Expand Up @@ -76,18 +75,13 @@ public DeployBeanPropertyLists(BeanDescriptorMap owner, BeanDescriptor<?> desc,

this.propertyMap = new LinkedHashMap<String, BeanProperty>();

Iterator<DeployBeanProperty> deployIt = deploy.propertiesAll();
while (deployIt.hasNext()) {
DeployBeanProperty deployProp = deployIt.next();
BeanProperty beanProp = createBeanProperty(owner, deployProp);
for (DeployBeanProperty prop : deploy.propertiesAll()) {
BeanProperty beanProp = createBeanProperty(owner, prop);
propertyMap.put(beanProp.getName(), beanProp);
}

Iterator<BeanProperty> it = propertyMap.values().iterator();

int order = 0;
while (it.hasNext()) {
BeanProperty prop = it.next();
for (BeanProperty prop : propertyMap.values()) {
prop.setDeployOrder(order++);
allocateToList(prop);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.avaje.ebeaninternal.server.deploy.parse;

import java.util.Iterator;

import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.JoinTable;
Expand Down Expand Up @@ -44,9 +42,7 @@ public AnnotationAssocManys(DeployBeanInfo<?> info, BeanDescriptorManager factor
* Parse the annotations.
*/
public void parse() {
Iterator<DeployBeanProperty> it = descriptor.propertiesAll();
while (it.hasNext()) {
DeployBeanProperty prop = it.next();
for (DeployBeanProperty prop : descriptor.propertiesAll()) {
if (prop instanceof DeployBeanPropertyAssocMany<?>) {
read((DeployBeanPropertyAssocMany<?>) prop);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.avaje.ebeaninternal.server.deploy.parse;

import java.util.Iterator;
import java.util.Map;

import javax.persistence.Column;
Expand Down Expand Up @@ -44,9 +43,7 @@ public AnnotationAssocOnes(DeployBeanInfo<?> info, BeanDescriptorManager factory
*/
public void parse() {

Iterator<DeployBeanProperty> it = descriptor.propertiesAll();
while (it.hasNext()) {
DeployBeanProperty prop = it.next();
for (DeployBeanProperty prop : descriptor.propertiesAll()) {
if (prop instanceof DeployBeanPropertyAssocOne<?>) {
readAssocOne((DeployBeanPropertyAssocOne<?>) prop);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.avaje.ebeaninternal.server.deploy.parse;

import java.sql.Types;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;

Expand Down Expand Up @@ -74,15 +73,12 @@ public AnnotationFields(DeployBeanInfo<?> info) {
*/
public void parse() {

Iterator<DeployBeanProperty> it = descriptor.propertiesAll();
while (it.hasNext()) {
DeployBeanProperty prop = it.next();
for (DeployBeanProperty prop : descriptor.propertiesAll()) {
if (prop instanceof DeployBeanPropertyAssoc<?>) {
readAssocOne(prop);
} else {
readField(prop);
}

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Iterator;

import javax.persistence.PersistenceException;
import javax.persistence.Transient;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.avaje.ebean.annotation.ColumnHstore;
import com.avaje.ebeaninternal.server.core.Message;
import com.avaje.ebeaninternal.server.deploy.DetermineManyType;
Expand All @@ -26,9 +28,6 @@
import com.avaje.ebeaninternal.server.type.TypeManager;
import com.avaje.ebeaninternal.server.type.reflect.CheckImmutableResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Create the properties for a bean.
* <p>
Expand Down Expand Up @@ -58,10 +57,7 @@ public void createProperties(DeployBeanDescriptor<?> desc) {
desc.sortProperties();

// check the transient properties...
Iterator<DeployBeanProperty> it = desc.propertiesAll();

while (it.hasNext()) {
DeployBeanProperty prop = it.next();
for (DeployBeanProperty prop : desc.propertiesAll()) {
if (prop.isTransient()) {
if (prop.getWriteMethod() == null || prop.getReadMethod() == null) {
// Typically a helper method ... this is expected
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.avaje.ebeaninternal.server.deploy;


import org.junit.Assert;
import org.junit.Test;

import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.tests.model.basic.ResetBasicData;
import com.avaje.tests.model.mappedsuper.ASimpleBean;

public class TestNotEnhancedMappedSuper extends BaseTestCase {

@Test
public void simpleBean_mappedSuperNotEnhanced_ok() {

// //GlobalProperties.put("ebean.search.packages", "com.avaje.tests.model.mappedsuper");

ResetBasicData.reset();

ASimpleBean bean = new ASimpleBean();
bean.setName("junk");

Ebean.save(bean);

Assert.assertNotNull(bean.getId());
}

}
30 changes: 30 additions & 0 deletions src/test/java/com/avaje/tests/model/mappedsuper/ASimpleBean.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.avaje.tests.model.mappedsuper;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class ASimpleBean extends NotEnhancedMappedSuper {

@Id
Long id;

String name;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.avaje.tests.model.mappedsuper;

import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;

@MappedSuperclass
public abstract class NotEnhancedMappedSuper {

public static String SOMETHING = "Hello";

private transient Long one;

@Transient
private Long two;

public Long getOne() {
return one;
}

public void setOne(Long one) {
this.one = one;
}

public Long getTwo() {
return two;
}

public void setTwo(Long two) {
this.two = two;
}

}

0 comments on commit 0c4fc4e

Please sign in to comment.