mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Merge pull request #3249 from ebean-orm/feature/bump-parent
Support native-image via querybean-generator
This commit is contained in:
@@ -237,7 +237,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
this.owner = owner;
|
||||
this.multiValueSupported = owner.isMultiValueSupported();
|
||||
this.entityType = deploy.getEntityType();
|
||||
this.properties = deploy.getProperties();
|
||||
this.properties = deploy.propertyNames();
|
||||
this.name = InternString.intern(deploy.getName());
|
||||
this.baseTableAlias = "t0";
|
||||
this.fullName = InternString.intern(deploy.getFullName());
|
||||
|
||||
+11
-13
@@ -443,11 +443,10 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
// build map of tables to view entities dependent on those tables
|
||||
// for the purpose of invalidating appropriate query caches
|
||||
String[] dependentTables = desc.dependentTables();
|
||||
if (dependentTables != null && dependentTables.length > 0) {
|
||||
if (dependentTables != null) {
|
||||
for (String depTable : dependentTables) {
|
||||
depTable = depTable.toLowerCase();
|
||||
List<BeanDescriptor<?>> list = tableToViewDescMap.computeIfAbsent(depTable, k -> new ArrayList<>(1));
|
||||
list.add(desc);
|
||||
tableToViewDescMap.computeIfAbsent(depTable, k -> new ArrayList<>(1)).add(desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -578,7 +577,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
}
|
||||
}
|
||||
|
||||
private <T> String errNothingRegistered() {
|
||||
private String errNothingRegistered() {
|
||||
return "There are no registered entities. If using query beans, that generates EbeanEntityRegister.java into " +
|
||||
"generated sources and is service loaded. If using module-info.java, then probably missing 'provides io.ebean.config.EntityClassRegister with EbeanEntityRegister' clause.";
|
||||
}
|
||||
@@ -1186,7 +1185,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
setConcurrencyMode(desc);
|
||||
}
|
||||
// generate the byte code
|
||||
createByteCode(desc);
|
||||
setAccessors(desc);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1255,13 +1254,13 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
return databasePlatform.createSequenceIdGenerator(backgroundExecutor, dataSource, stepSize, seqName);
|
||||
}
|
||||
|
||||
private void createByteCode(DeployBeanDescriptor<?> deploy) {
|
||||
private void setAccessors(DeployBeanDescriptor<?> deploy) {
|
||||
// check to see if the bean supports EntityBean interface
|
||||
// generate a subclass if required
|
||||
setEntityBeanClass(deploy);
|
||||
confirmEnhanced(deploy);
|
||||
// use Code generation or Standard reflection to support
|
||||
// getter and setter methods
|
||||
setBeanReflect(deploy);
|
||||
setPropertyAccessors(deploy);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1288,15 +1287,14 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
* and getting of properties. It is generally faster to use code generation
|
||||
* rather than reflection to do this.
|
||||
*/
|
||||
private void setBeanReflect(DeployBeanDescriptor<?> desc) {
|
||||
private void setPropertyAccessors(DeployBeanDescriptor<?> desc) {
|
||||
// Set the BeanReflectGetter and BeanReflectSetter that typically
|
||||
// use generated code. NB: Due to Bug 166 so now doing this for
|
||||
// abstract classes as well.
|
||||
BeanPropertiesReader reflectProps = new BeanPropertiesReader(desc.getBeanType());
|
||||
desc.setProperties(reflectProps.getProperties());
|
||||
BeanPropertiesReader reflectProps = new BeanPropertiesReader(desc.propertyNames());
|
||||
for (DeployBeanProperty prop : desc.propertiesAll()) {
|
||||
String propName = prop.getName();
|
||||
Integer pos = reflectProps.getPropertyIndex(propName);
|
||||
Integer pos = reflectProps.propertyIndex(propName);
|
||||
if (pos == null) {
|
||||
if (isPersistentField(prop)) {
|
||||
throw new IllegalStateException(
|
||||
@@ -1368,7 +1366,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
/**
|
||||
* Test the bean type to see if it implements EntityBean interface already.
|
||||
*/
|
||||
private void setEntityBeanClass(DeployBeanDescriptor<?> desc) {
|
||||
private void confirmEnhanced(DeployBeanDescriptor<?> desc) {
|
||||
Class<?> beanClass = desc.getBeanType();
|
||||
if (!hasEntityBeanInterface(beanClass)) {
|
||||
String msg = "Bean " + beanClass + " is not enhanced? Check packages specified in ebean.mf. If you are running in IDEA or " +
|
||||
|
||||
+23
-25
@@ -24,6 +24,8 @@ import io.ebeaninternal.server.rawsql.SpiRawSql;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@@ -45,8 +47,6 @@ public class DeployBeanDescriptor<T> {
|
||||
|
||||
private static final PropOrder PROP_ORDER = new PropOrder();
|
||||
|
||||
private static final String I_SCALAOBJECT = "scala.ScalaObject";
|
||||
|
||||
private final DatabaseConfig config;
|
||||
private final BeanDescriptorManager manager;
|
||||
/**
|
||||
@@ -139,10 +139,30 @@ public class DeployBeanDescriptor<T> {
|
||||
this.beanType = beanType;
|
||||
}
|
||||
|
||||
private String[] readPropertyNames() {
|
||||
try {
|
||||
Field field = beanType.getField("_ebean_props");
|
||||
return (String[]) field.get(null);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Error getting _ebean_props field on type " + beanType, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setPropertyNames(String[] properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public String[] propertyNames() {
|
||||
if (properties == null) {
|
||||
properties = readPropertyNames();
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the IdClass to use.
|
||||
*/
|
||||
public void setIdClass(Class idClass) {
|
||||
public void setIdClass(Class<?> idClass) {
|
||||
this.idClass = idClass;
|
||||
}
|
||||
|
||||
@@ -260,7 +280,6 @@ public class DeployBeanDescriptor<T> {
|
||||
* Read the top level doc store deployment information.
|
||||
*/
|
||||
public void readDocStore(DocStore docStore) {
|
||||
|
||||
this.docStore = docStore;
|
||||
docStoreMapped = true;
|
||||
docStoreQueueId = docStore.queueId();
|
||||
@@ -276,23 +295,10 @@ public class DeployBeanDescriptor<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isScalaObject() {
|
||||
Class<?>[] interfaces = beanType.getInterfaces();
|
||||
for (Class<?> anInterface : interfaces) {
|
||||
String iname = anInterface.getName();
|
||||
if (I_SCALAOBJECT.equals(iname)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public DeployBeanTable createDeployBeanTable() {
|
||||
|
||||
DeployBeanTable beanTable = new DeployBeanTable(getBeanType());
|
||||
beanTable.setBaseTable(baseTable);
|
||||
beanTable.setIdProperty(idProperty());
|
||||
|
||||
return beanTable;
|
||||
}
|
||||
|
||||
@@ -360,14 +366,6 @@ public class DeployBeanDescriptor<T> {
|
||||
this.identityMode.setIdType(type);
|
||||
}
|
||||
|
||||
public String[] getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setProperties(String[] props) {
|
||||
this.properties = props;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the class type this BeanDescriptor describes.
|
||||
*/
|
||||
|
||||
+2
-2
@@ -213,9 +213,9 @@ final class AnnotationAssocManys extends AnnotationAssoc {
|
||||
|
||||
int sortOrder = 0;
|
||||
if (!prop.getManyType().isMap()) {
|
||||
elementDescriptor.setProperties(new String[]{"value"});
|
||||
elementDescriptor.setPropertyNames(new String[]{"value"});
|
||||
} else {
|
||||
elementDescriptor.setProperties(new String[]{"key", "value"});
|
||||
elementDescriptor.setPropertyNames(new String[]{"key", "value"});
|
||||
String dbKeyColumn = "mkey";
|
||||
MapKeyColumn mapKeyColumn = get(prop, MapKeyColumn.class);
|
||||
if (mapKeyColumn != null) {
|
||||
|
||||
+2
-24
@@ -1,7 +1,5 @@
|
||||
package io.ebeaninternal.server.properties;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -11,34 +9,14 @@ import java.util.Map;
|
||||
public final class BeanPropertiesReader {
|
||||
|
||||
private final Map<String, Integer> propertyIndexMap = new HashMap<>();
|
||||
private final String[] props;
|
||||
|
||||
public BeanPropertiesReader(Class<?> clazz) {
|
||||
this.props = getProperties(clazz);
|
||||
public BeanPropertiesReader(String[] props) {
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
propertyIndexMap.put(props[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getProperties() {
|
||||
return props;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Arrays.toString(props);
|
||||
}
|
||||
|
||||
public Integer getPropertyIndex(String property) {
|
||||
public Integer propertyIndex(String property) {
|
||||
return propertyIndexMap.get(property);
|
||||
}
|
||||
|
||||
private String[] getProperties(Class<?> clazz) {
|
||||
try {
|
||||
Field field = clazz.getField("_ebean_props");
|
||||
return (String[]) field.get(null);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Error getting _ebean_props field on type " + clazz, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -7,6 +7,7 @@ import io.ebeaninternal.server.deploy.generatedproperty.GeneratedPropertyFactory
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
|
||||
import io.ebeaninternal.server.type.DefaultTypeManager;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.tests.model.basic.Customer;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
@@ -47,7 +48,7 @@ public class AnnotationClassTest {
|
||||
private AnnotationClass createAnnotationClass(DatabaseConfig config) {
|
||||
DeployUtil deployUtil = new DeployUtil(new DefaultTypeManager(config, new BootupClasses()), config);
|
||||
|
||||
DeployBeanInfo deployBeanInfo = new DeployBeanInfo(deployUtil, new DeployBeanDescriptor<>(null, null, null));
|
||||
DeployBeanInfo deployBeanInfo = new DeployBeanInfo(deployUtil, new DeployBeanDescriptor<>(null, Customer.class, null));
|
||||
ReadAnnotationConfig readAnnotationConfig = new ReadAnnotationConfig(new GeneratedPropertyFactory(true, new DatabaseConfig(), Collections.emptyList()), "","", new DatabaseConfig());
|
||||
return new AnnotationClass(deployBeanInfo, readAnnotationConfig);
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
<source>11</source>
|
||||
<target>11</target>
|
||||
<!-- Turn off annotation processing for building -->
|
||||
<compilerArgument>-proc:none</compilerArgument>
|
||||
<compilerArgs>-proc:none</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<source>11</source>
|
||||
<target>11</target>
|
||||
<!-- Turn off annotation processing for building -->
|
||||
<compilerArgument>-proc:none</compilerArgument>
|
||||
<compilerArgs>-proc:none</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
@@ -475,6 +475,11 @@ class ProcessingContext implements Constants {
|
||||
return createMetaInfWriter(METAINF_MANIFEST);
|
||||
}
|
||||
|
||||
FileObject createNativeImageWriter(String name) throws IOException {
|
||||
String nm = "META-INF/native-image/" + name + "/reflect-config.json";
|
||||
return createMetaInfWriter(nm);
|
||||
}
|
||||
|
||||
FileObject createMetaInfWriter(String target) throws IOException {
|
||||
return filer.createResource(StandardLocation.CLASS_OUTPUT, "", target);
|
||||
}
|
||||
|
||||
+35
-7
@@ -4,6 +4,7 @@ import javax.tools.FileObject;
|
||||
import javax.tools.JavaFileObject;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
@@ -38,6 +39,7 @@ class SimpleModuleInfoWriter {
|
||||
writer.close();
|
||||
writeServicesFile();
|
||||
writeManifestFile();
|
||||
writeNativeImageFile();
|
||||
}
|
||||
|
||||
private void writeServicesFile() {
|
||||
@@ -48,9 +50,7 @@ class SimpleModuleInfoWriter {
|
||||
writer.write(factoryFullName);
|
||||
writer.close();
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
processingContext.logError(null, "Failed to write services file " + e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -68,9 +68,7 @@ class SimpleModuleInfoWriter {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
processingContext.logError(null, "Failed to write services file " + e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -84,10 +82,41 @@ class SimpleModuleInfoWriter {
|
||||
return builder.delete(builder.lastIndexOf("\n"), builder.length()).append('\n').toString();
|
||||
}
|
||||
|
||||
private void writeNativeImageFile() {
|
||||
try {
|
||||
Set<String> allEntities = new LinkedHashSet<>(processingContext.getDbEntities());
|
||||
for (Set<String> value : processingContext.getOtherDbEntities().values()) {
|
||||
allEntities.addAll(value);
|
||||
}
|
||||
|
||||
if (!allEntities.isEmpty()) {
|
||||
FileObject jfo = processingContext.createNativeImageWriter(factoryPackage + ".ebean-entity");
|
||||
if (jfo != null) {
|
||||
boolean first = true;
|
||||
Writer writer = jfo.openWriter();
|
||||
writer.write("[");
|
||||
for (String entity : allEntities) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
writer.write(",");
|
||||
}
|
||||
writer.write("\n {\"name\": \"");
|
||||
writer.write(entity);
|
||||
writer.write("\", \"allDeclaredConstructors\": true, \"allDeclaredFields\": true}");
|
||||
}
|
||||
writer.write("\n]\n");
|
||||
writer.write("\n");
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
processingContext.logError(null, "Failed to write services file " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void writePackage() {
|
||||
|
||||
writer.append("package %s;", factoryPackage).eol().eol();
|
||||
|
||||
writer.append("import java.util.ArrayList;").eol();
|
||||
writer.append("import java.util.Collections;").eol();
|
||||
writer.append("import java.util.List;").eol();
|
||||
@@ -125,7 +154,6 @@ class SimpleModuleInfoWriter {
|
||||
}
|
||||
|
||||
private void writeStartClass() {
|
||||
|
||||
buildAtContextModule(writer);
|
||||
|
||||
writer.append("public class %s implements EntityClassRegister {", factoryShortName).eol().eol();
|
||||
|
||||
Reference in New Issue
Block a user