use of io.micronaut.data.model.PersistentEntity in project micronaut-data by micronaut-projects.
the class AbstractQueryInterceptor method instantiateEntity.
/**
* Instantiate the given entity for the given parameter values.
*
* @param rootEntity The entity
* @param parameterValues The parameter values
* @return The entity
* @throws IllegalArgumentException if the entity cannot be instantiated due to an illegal argument
*/
@NonNull
protected Object instantiateEntity(@NonNull Class<?> rootEntity, @NonNull Map<String, Object> parameterValues) {
PersistentEntity entity = operations.getEntity(rootEntity);
BeanIntrospection<?> introspection = BeanIntrospection.getIntrospection(rootEntity);
Argument<?>[] constructorArguments = introspection.getConstructorArguments();
Object instance;
if (ArrayUtils.isNotEmpty(constructorArguments)) {
Object[] arguments = new Object[constructorArguments.length];
for (int i = 0; i < constructorArguments.length; i++) {
Argument<?> argument = constructorArguments[i];
String argumentName = argument.getName();
Object v = parameterValues.get(argumentName);
AnnotationMetadata argMetadata = argument.getAnnotationMetadata();
if (v == null && !PersistentProperty.isNullableMetadata(argMetadata)) {
PersistentProperty prop = entity.getPropertyByName(argumentName);
if (prop == null || prop.isRequired()) {
throw new IllegalArgumentException("Argument [" + argumentName + "] cannot be null");
}
}
arguments[i] = v;
}
instance = introspection.instantiate(arguments);
} else {
instance = introspection.instantiate();
}
BeanWrapper<Object> wrapper = BeanWrapper.getWrapper(instance);
Collection<? extends PersistentProperty> persistentProperties = entity.getPersistentProperties();
for (PersistentProperty prop : persistentProperties) {
if (!prop.isReadOnly() && !prop.isGenerated()) {
String propName = prop.getName();
if (parameterValues.containsKey(propName)) {
Object v = parameterValues.get(propName);
if (v == null && !prop.isOptional()) {
throw new IllegalArgumentException("Argument [" + propName + "] cannot be null");
}
wrapper.setProperty(propName, v);
} else if (prop.isRequired()) {
final Optional<Object> p = wrapper.getProperty(propName, Object.class);
if (!p.isPresent()) {
throw new IllegalArgumentException("Argument [" + propName + "] cannot be null");
}
}
}
}
return instance;
}
use of io.micronaut.data.model.PersistentEntity in project micronaut-data by micronaut-projects.
the class SchemaGenerator method createSchema.
/**
* Initialize the schema for the configuration.
* @param beanLocator The bean locator
*/
@PostConstruct
public void createSchema(BeanLocator beanLocator) {
RuntimeEntityRegistry runtimeEntityRegistry = beanLocator.getBean(RuntimeEntityRegistry.class);
for (DataJdbcConfiguration configuration : configurations) {
Dialect dialect = configuration.getDialect();
SchemaGenerate schemaGenerate = configuration.getSchemaGenerate();
if (schemaGenerate != null && schemaGenerate != SchemaGenerate.NONE) {
String name = configuration.getName();
List<String> packages = configuration.getPackages();
Collection<BeanIntrospection<Object>> introspections;
if (CollectionUtils.isNotEmpty(packages)) {
introspections = BeanIntrospector.SHARED.findIntrospections(MappedEntity.class, packages.toArray(new String[0]));
} else {
introspections = BeanIntrospector.SHARED.findIntrospections(MappedEntity.class);
}
PersistentEntity[] entities = introspections.stream().filter(i -> !i.getBeanType().getName().contains("$")).filter(i -> !java.lang.reflect.Modifier.isAbstract(i.getBeanType().getModifiers())).map(beanIntrospection -> runtimeEntityRegistry.getEntity(beanIntrospection.getBeanType())).toArray(PersistentEntity[]::new);
if (ArrayUtils.isNotEmpty(entities)) {
DataSource dataSource = DelegatingDataSource.unwrapDataSource(beanLocator.getBean(DataSource.class, Qualifiers.byName(name)));
try {
try (Connection connection = dataSource.getConnection()) {
SqlQueryBuilder builder = new SqlQueryBuilder(dialect);
if (dialect.allowBatch() && configuration.isBatchGenerate()) {
switch(schemaGenerate) {
case CREATE_DROP:
try {
String sql = builder.buildBatchDropTableStatement(entities);
if (DataSettings.QUERY_LOG.isDebugEnabled()) {
DataSettings.QUERY_LOG.debug("Dropping Tables: \n{}", sql);
}
try (PreparedStatement ps = connection.prepareStatement(sql)) {
ps.executeUpdate();
}
} catch (SQLException e) {
if (DataSettings.QUERY_LOG.isTraceEnabled()) {
DataSettings.QUERY_LOG.trace("Drop Unsuccessful: " + e.getMessage());
}
}
case CREATE:
String sql = builder.buildBatchCreateTableStatement(entities);
if (DataSettings.QUERY_LOG.isDebugEnabled()) {
DataSettings.QUERY_LOG.debug("Creating Tables: \n{}", sql);
}
try (PreparedStatement ps = connection.prepareStatement(sql)) {
ps.executeUpdate();
}
break;
default:
}
} else {
switch(schemaGenerate) {
case CREATE_DROP:
for (PersistentEntity entity : entities) {
try {
String[] statements = builder.buildDropTableStatements(entity);
for (String sql : statements) {
if (DataSettings.QUERY_LOG.isDebugEnabled()) {
DataSettings.QUERY_LOG.debug("Dropping Table: \n{}", sql);
}
try (PreparedStatement ps = connection.prepareStatement(sql)) {
ps.executeUpdate();
}
}
} catch (SQLException e) {
if (DataSettings.QUERY_LOG.isTraceEnabled()) {
DataSettings.QUERY_LOG.trace("Drop Unsuccessful: " + e.getMessage());
}
}
}
case CREATE:
for (PersistentEntity entity : entities) {
String[] sql = builder.buildCreateTableStatements(entity);
for (String stmt : sql) {
if (DataSettings.QUERY_LOG.isDebugEnabled()) {
DataSettings.QUERY_LOG.debug("Executing CREATE statement: \n{}", stmt);
}
try {
try (PreparedStatement ps = connection.prepareStatement(stmt)) {
ps.executeUpdate();
}
} catch (SQLException e) {
if (DataSettings.QUERY_LOG.isWarnEnabled()) {
DataSettings.QUERY_LOG.warn("CREATE Statement Unsuccessful: " + e.getMessage());
}
}
}
}
break;
default:
}
}
} catch (SQLException e) {
throw new DataAccessException("Unable to create database schema: " + e.getMessage(), e);
}
} catch (NoSuchBeanException e) {
throw new ConfigurationException("No DataSource configured for setting [" + DataJdbcConfiguration.PREFIX + name + "]. Ensure the DataSource is configured correctly and try again.", e);
}
}
}
}
}
use of io.micronaut.data.model.PersistentEntity in project micronaut-data by micronaut-projects.
the class MongoQueryBuilder method traversePersistentProperties.
private void traversePersistentProperties(List<Association> associations, PersistentProperty property, BiConsumer<List<Association>, PersistentProperty> consumerProperty) {
if (property instanceof Embedded) {
Embedded embedded = (Embedded) property;
PersistentEntity embeddedEntity = embedded.getAssociatedEntity();
Collection<? extends PersistentProperty> embeddedProperties = embeddedEntity.getPersistentProperties();
List<Association> newAssociations = new ArrayList<>(associations);
newAssociations.add((Association) property);
for (PersistentProperty embeddedProperty : embeddedProperties) {
traversePersistentProperties(newAssociations, embeddedProperty, consumerProperty);
}
} else if (property instanceof Association) {
Association association = (Association) property;
if (association.isForeignKey()) {
return;
}
List<Association> newAssociations = new ArrayList<>(associations);
newAssociations.add((Association) property);
PersistentEntity associatedEntity = association.getAssociatedEntity();
PersistentProperty assocIdentity = associatedEntity.getIdentity();
if (assocIdentity == null) {
throw new IllegalStateException("Identity cannot be missing for: " + associatedEntity);
}
if (assocIdentity instanceof Association) {
traversePersistentProperties(newAssociations, assocIdentity, consumerProperty);
} else {
consumerProperty.accept(newAssociations, assocIdentity);
}
} else {
consumerProperty.accept(associations, property);
}
}
use of io.micronaut.data.model.PersistentEntity in project micronaut-data by micronaut-projects.
the class SqlQueryBuilder method buildJoinTableInsert.
/**
* Builds a join table insert statement for a given entity and association.
*
* @param entity The entity
* @param association The association
* @return The join table insert statement
*/
@NonNull
public String buildJoinTableInsert(@NonNull PersistentEntity entity, @NonNull Association association) {
if (!isForeignKeyWithJoinTable(association)) {
throw new IllegalArgumentException("Join table inserts can only be built for foreign key associations that are mapped with a join table.");
} else {
Optional<Association> inverseSide = association.getInverseSide().map(Function.identity());
Association owningAssociation = inverseSide.orElse(association);
AnnotationMetadata annotationMetadata = owningAssociation.getAnnotationMetadata();
NamingStrategy namingStrategy = entity.getNamingStrategy();
String joinTableName = annotationMetadata.stringValue(ANN_JOIN_TABLE, "name").orElseGet(() -> namingStrategy.mappedName(association));
List<String> leftJoinColumns = resolveJoinTableJoinColumns(annotationMetadata, true, entity, namingStrategy);
List<String> rightJoinColumns = resolveJoinTableJoinColumns(annotationMetadata, false, association.getAssociatedEntity(), namingStrategy);
boolean escape = shouldEscape(entity);
String columns = Stream.concat(leftJoinColumns.stream(), rightJoinColumns.stream()).map(columnName -> escape ? quote(columnName) : columnName).collect(Collectors.joining(","));
String placeholders = IntStream.range(0, leftJoinColumns.size() + rightJoinColumns.size()).mapToObj(i -> "?").collect(Collectors.joining(","));
return INSERT_INTO + quote(joinTableName) + " (" + columns + ") VALUES (" + placeholders + ")";
}
}
use of io.micronaut.data.model.PersistentEntity in project micronaut-data by micronaut-projects.
the class SqlQueryBuilder method buildJoin.
@Override
protected String[] buildJoin(final String alias, JoinPath joinPath, String joinType, StringBuilder target, Map<String, String> appliedJoinPaths, QueryState queryState) {
Association[] associationPath = joinPath.getAssociationPath();
String[] joinAliases;
if (ArrayUtils.isEmpty(associationPath)) {
throw new IllegalArgumentException("Invalid association path [" + joinPath.getPath() + "]");
}
List<Association> joinAssociationsPath = new ArrayList<>(associationPath.length);
joinAliases = new String[associationPath.length];
StringJoiner pathSoFar = new StringJoiner(".");
String joinAlias = alias;
for (int i = 0; i < associationPath.length; i++) {
Association association = associationPath[i];
pathSoFar.add(association.getName());
if (association instanceof Embedded) {
joinAssociationsPath.add(association);
continue;
}
String currentPath = pathSoFar.toString();
String existingAlias = appliedJoinPaths.get(currentPath);
if (existingAlias != null) {
joinAliases[i] = existingAlias;
joinAlias = existingAlias;
} else {
PersistentEntity associatedEntity = association.getAssociatedEntity();
int finalI = i;
JoinPath joinPathToUse = queryState.getQueryModel().getJoinPath(currentPath).orElseGet(() -> new JoinPath(currentPath, Arrays.copyOfRange(associationPath, 0, finalI + 1), joinPath.getJoinType(), joinPath.getAlias().orElse(null)));
joinAliases[i] = getAliasName(joinPathToUse);
String currentJoinAlias = joinAliases[i];
buildJoin(joinType, target, queryState, joinAssociationsPath, joinAlias, association, associatedEntity, findOwner(joinAssociationsPath, association).orElseGet(queryState::getEntity), currentJoinAlias);
joinAlias = currentJoinAlias;
}
joinAssociationsPath.clear();
}
return joinAliases;
}
Aggregations