Prevent ExtendedBeanSerializer from generating 2 toString methods

This commit is contained in:
Ilya Litosh 2020-07-19 11:55:52 +01:00 committed by Jan-Willem Gmelig Meyling
parent 852b48a4ca
commit 8e4bedb4ca
3 changed files with 144 additions and 6 deletions

View File

@ -43,6 +43,7 @@ A huge thanks goes out to all contributors that made this release possible in th
* [#2504](https://github.com/querydsl/querydsl/issues/2504) - Work around issues with `AbstractJPAQuery#fetchResults` and `AbstractJPAQuery#fetchCount` in a query with multiple group by expressions by using an in-memory calculation.
* [#2663](https://github.com/querydsl/querydsl/issues/2663) - Fix issues with the JPA implementation of `InsertClause`.
* [#2706](https://github.com/querydsl/querydsl/pull/2706) - Fix a memory leak in `TemplateFactory`.
* [#2467](https://github.com/querydsl/querydsl/issues/2467) - Prevent `ExtendedBeanSerializer` from generating `toString` method twice
#### Breaking changes

View File

@ -54,7 +54,6 @@ public class ExtendedBeanSerializer extends BeanSerializer {
StringBuilder anyColumnIsNull = new StringBuilder();
StringBuilder columnEquals = new StringBuilder();
StringBuilder toString = new StringBuilder();
List<String> properties = new ArrayList<String>();
for (PrimaryKeyData pk : primaryKeys) {
for (String column : pk.getColumns()) {
@ -63,13 +62,9 @@ public class ExtendedBeanSerializer extends BeanSerializer {
if (anyColumnIsNull.length() > 0) {
anyColumnIsNull.append(" || ");
columnEquals.append(" && ");
toString.append("+ \";\" + ");
} else {
toString.append("\"").append(model.getSimpleName()).append("#\" + ");
}
anyColumnIsNull.append(propName).append(" == null");
columnEquals.append(propName).append(".equals(obj.").append(propName).append(")");
toString.append(propName);
properties.add(propName);
}
}
@ -101,6 +96,37 @@ public class ExtendedBeanSerializer extends BeanSerializer {
writer.line("return result;");
writer.end();
}
@Override
protected void addToString(EntityType model, CodeWriter writer) throws IOException {
Collection<PrimaryKeyData> primaryKeys = (Collection<PrimaryKeyData>) model.getData().get(PrimaryKeyData.class);
if (primaryKeys == null || primaryKeys.isEmpty()) {
super.addToString(model, writer);
return;
}
StringBuilder toString = new StringBuilder();
Map<String, Property> columnToProperty = new HashMap<String, Property>();
for (Property property : model.getProperties()) {
columnToProperty.put(property.getAnnotation(Column.class).value(), property);
}
for (PrimaryKeyData pk : primaryKeys) {
for (String column : pk.getColumns()) {
Property property = columnToProperty.get(column);
String propName = property.getEscapedName();
if (toString.length() > 0) {
toString.append("+ \";\" + ");
} else {
toString.append("\"" + model.getSimpleName() + "#\" + ");
}
toString.append(propName);
}
}
// toString
writer.annotation(Override.class);
writer.beginPublicMethod(Types.STRING, "toString");
@ -109,7 +135,6 @@ public class ExtendedBeanSerializer extends BeanSerializer {
// writer.line("}");
writer.line("return ", toString + ";");
writer.end();
}
}

View File

@ -0,0 +1,112 @@
package com.querydsl.sql.codegen;
import com.querydsl.codegen.EntityType;
import com.querydsl.codegen.Property;
import com.querydsl.codegen.SimpleSerializerConfig;
import com.querydsl.codegen.utils.JavaWriter;
import com.querydsl.codegen.utils.SimpleCompiler;
import com.querydsl.codegen.utils.model.ClassType;
import com.querydsl.codegen.utils.model.SimpleType;
import com.querydsl.codegen.utils.model.Type;
import com.querydsl.codegen.utils.model.TypeCategory;
import com.querydsl.sql.ColumnImpl;
import com.querydsl.sql.codegen.support.PrimaryKeyData;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
public class ExtendedBeanSerializerTest {
private static final String CLASS_NAME = "DomainClass";
private static final String[] PATH = {"com", "querydsl", "test", "gen"};
private static final String PACKAGE = String.join(".", PATH);
private static final String FULL_NAME = PACKAGE + "." + CLASS_NAME;
@Rule
public TemporaryFolder compileFolder = new TemporaryFolder();
private EntityType type;
private File srcFile;
@Before
public void setUp() throws IOException {
Type typeModel = new SimpleType(TypeCategory.ENTITY, FULL_NAME, PACKAGE, CLASS_NAME, false, false);
type = new EntityType(typeModel);
File srcFolder = compileFolder.newFolder(PATH);
srcFile = new File(srcFolder, CLASS_NAME + ".java");
}
@Test
public void equals_hashcode_tostring() throws Exception {
Property idCol = new Property(type, "id", new ClassType(Integer.class));
idCol.addAnnotation(new ColumnImpl("ID"));
Property subIdCol = new Property(type, "sub_id", new ClassType(String.class));
subIdCol.addAnnotation(new ColumnImpl("SUB_ID"));
Property nameCol = new Property(type, "name", new ClassType(String.class));
nameCol.addAnnotation(new ColumnImpl("NAME"));
type.addProperty(idCol);
type.addProperty(subIdCol);
type.addProperty(nameCol);
type.getData().put(PrimaryKeyData.class, Arrays.asList(
new PrimaryKeyData("PK", new String[]{"ID", "SUB_ID"})));
ExtendedBeanSerializer extendedBeanSerializer = new ExtendedBeanSerializer();
extendedBeanSerializer.setAddToString(true);
FileWriter fw = new FileWriter(srcFile);
extendedBeanSerializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(fw));
fw.close();
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] {compileFolder.getRoot().toURI().toURL()});
int retCode = new SimpleCompiler().run(null, System.out, System.err, srcFile.getAbsolutePath());
assertEquals("The generated source should compile", 0, retCode);
Class<?> cls = Class.forName(FULL_NAME, true, classLoader);
ReflectionHelper reflection = new ReflectionHelper(cls);
Object obj1 = cls.newInstance();
Object obj1a = cls.newInstance();
Object obj2 = cls.newInstance();
reflection.setValues(obj1, 1, "##", "X");
reflection.setValues(obj1a, 1, "##", null);
reflection.setValues(obj2, 2, "--", "Y");
assertEquals(obj1, obj1a);
assertEquals(obj1.hashCode(), obj1a.hashCode());
assertNotEquals(obj1, obj2);
assertEquals(obj1.toString(), "DomainClass#1;##");
}
private static class ReflectionHelper {
private final Map<String, Method> methodByName = new HashMap<String, Method>();
public ReflectionHelper(Class<?> cls) {
for (Method m : cls.getDeclaredMethods()) {
methodByName.put(m.getName(), m);
}
}
private void setValues(Object instance, int id, String subId, String name) throws Exception {
methodByName.get("setId").invoke(instance, id);
methodByName.get("setSub_id").invoke(instance, subId);
methodByName.get("setName").invoke(instance, name);
}
}
}