protected PropertyMeta parseSimpleProperty(PropertyParsingContext context) { log.debug( "Parsing property {} as simple property of entity class {}", context.getCurrentPropertyName(), context.getCurrentEntityClass().getCanonicalName()); Class<?> entityClass = context.getCurrentEntityClass(); Field field = context.getCurrentField(); boolean timeUUID = isTimeUUID(context, field); Method[] accessors = entityIntrospector.findAccessors(entityClass, field); PropertyType type = SIMPLE; PropertyMeta propertyMeta = factory() .objectMapper(context.getCurrentObjectMapper()) .type(type) .propertyName(context.getCurrentPropertyName()) .entityClassName(context.getCurrentEntityClass().getCanonicalName()) .accessors(accessors) .consistencyLevels(context.getCurrentConsistencyLevels()) .field(field) .timeuuid(timeUUID) .build(Void.class, field.getType()); log.trace( "Built simple property meta for property {} of entity class {} : {}", propertyMeta.getPropertyName(), context.getCurrentEntityClass().getCanonicalName(), propertyMeta); return propertyMeta; }
public <T> T buildProxy(T entity, EntityOperations context, Set<Method> alreadyLoaded) { if (entity == null) { return null; } log.debug("Build Cglib proxy for entity {} ", entity); Class<?> proxyClass = factory.createProxyClass(entity.getClass(), context.getConfigContext()); @SuppressWarnings("unchecked") T instance = (T) instantiator.instantiate(proxyClass); EntityMeta meta = context.getEntityMeta(); for (PropertyMeta pm : meta.getAllMetasExceptCounters()) { Object value = pm.forValues().getValueFromField(entity); pm.forValues().setValueToField(instance, value); } for (PropertyMeta pm : meta.getAllCounterMetas()) { pm.forValues().setValueToField(entity, null); } ((Factory) instance) .setCallbacks(new Callback[] {buildInterceptor(context, entity, alreadyLoaded)}); return instance; }
private void validatePrimaryKeyComponents( TableMetadata tableMetadata, PropertyMeta idMeta, boolean partitionKey) { log.debug( "Validate existing primary key component from table {} against Achilles meta data {}", tableMetadata.getName(), idMeta); List<String> componentNames; List<Class<?>> componentClasses; if (partitionKey) { componentNames = idMeta.getPartitionComponentNames(); componentClasses = idMeta.getPartitionComponentClasses(); } else { componentNames = idMeta.getClusteringComponentNames(); componentClasses = idMeta.getClusteringComponentClasses(); } for (int i = 0; i < componentNames.size(); i++) { Class<?> componentClass = componentClasses.get(i); String componentName = componentNames.get(i); if (idMeta.isComponentTimeUUID(componentName)) { componentClass = InternalTimeUUID.class; } if (partitionKey) validatePartitionComponent(tableMetadata, componentName.toLowerCase(), componentClass); else validateClusteringComponent(tableMetadata, componentName.toLowerCase(), componentClass); } }
private Object[] extractValuesForSimpleCounterBinding( EntityMeta entityMeta, PropertyMeta pm, Object primaryKey) { PropertyMeta idMeta = entityMeta.getIdMeta(); String fqcn = entityMeta.getClassName(); String primaryKeyAsString = idMeta.forTranscoding().forceEncodeToJSONForCounter(primaryKey); String cql3ColumnName = pm.getCQL3ColumnName(); return new Object[] {fqcn, primaryKeyAsString, cql3ColumnName}; }
private List<Object> fetchPropertiesValues(List<PropertyMeta> pms, Object entity) { List<Object> values = new ArrayList<>(); for (PropertyMeta pm : pms) { Object value = pm.forTranscoding().getAndEncodeValueForCassandra(entity); values.add(value); } return values; }
private List<Object> bindPrimaryKey( Object primaryKey, PropertyMeta idMeta, boolean onlyStaticColumns) { List<Object> values = new ArrayList<>(); if (idMeta.structure().isEmbeddedId()) { values.addAll(idMeta.forTranscoding().encodeToComponents(primaryKey, onlyStaticColumns)); } else { values.add(idMeta.forTranscoding().encodeToCassandra(primaryKey)); } return values; }
private void validateTable( EntityMeta entityMeta, TableMetadata tableMetadata, PropertyMeta idMeta) { if (idMeta.isEmbeddedId()) { validatePrimaryKeyComponents(tableMetadata, idMeta, true); validatePrimaryKeyComponents(tableMetadata, idMeta, false); } else { validateColumn( tableMetadata, idMeta.getPropertyName().toLowerCase(), idMeta.getValueClassForTableCreation(), idMeta.isIndexed()); } for (PropertyMeta pm : entityMeta.getAllMetasExceptIdAndCounters()) { switch (pm.type()) { case SIMPLE: validateColumn( tableMetadata, pm.getPropertyName().toLowerCase(), pm.getValueClassForTableCreation(), pm.isIndexed()); break; case LIST: case SET: case MAP: validateCollectionAndMapColumn(tableMetadata, pm); break; default: break; } } }
public void loadPropertyIntoObject( PersistenceContext context, Object realObject, PropertyMeta pm) { log.trace("Loading property {} into object {}", pm.getPropertyName(), realObject); PropertyType type = pm.type(); if (type.isCounter()) { counterLoader.loadCounter(context, realObject, pm); } else { Row row = context.loadProperty(pm); mapper.setPropertyToEntity(row, pm, realObject); } }
protected PropertyMeta parseId(PropertyParsingContext context) { log.debug( "Parsing property {} as id of entity class {}", context.getCurrentPropertyName(), context.getCurrentEntityClass().getCanonicalName()); PropertyMeta idMeta = parseSimpleProperty(context); idMeta.setType(ID); Id id = context.getCurrentField().getAnnotation(Id.class); String propertyName = StringUtils.isNotBlank(id.name()) ? id.name() : context.getCurrentPropertyName(); idMeta.setPropertyName(propertyName); return idMeta; }
public BoundStatementWrapper bindForClusteredCounterIncrementDecrement( PersistentStateHolder context, PreparedStatement ps, PropertyMeta counterMeta, Long increment) { EntityMeta entityMeta = context.getEntityMeta(); Object primaryKey = context.getPrimaryKey(); log.trace( "Bind prepared statement {} for clustered counter increment/decrement for {} using primary key {} and value {}", ps.getQueryString(), entityMeta, primaryKey, increment); ConsistencyLevel consistencyLevel = overrider.getWriteLevel(context); List<Object> primaryKeys = bindPrimaryKey( primaryKey, entityMeta.getIdMeta(), counterMeta.structure().isStaticColumn()); Object[] keys = addAll(new Object[] {increment}, primaryKeys.toArray()); BoundStatement bs = ps.bind(keys); return new BoundStatementWrapper( context.getEntityClass(), bs, keys, getCQLLevel(consistencyLevel), NO_LISTENER, NO_SERIAL_CONSISTENCY); }
@Test public void should_update_table_with_new_indexed_simple_field() throws Exception { // Given PropertyMeta idMeta = valueClass(Long.class).type(PARTITION_KEY).cqlColumnName("id").build(); PropertyMeta longColPM = valueClass(Long.class).type(SIMPLE).cqlColumnName("longcol").build(); longColPM.setIndexProperties(new IndexProperties("long_index", "longCol")); when(meta.getAllMetasExceptId()).thenReturn(asList(longColPM)); when(meta.getIdMeta()).thenReturn(idMeta); when(tableMeta.getColumns()).thenReturn(Arrays.<ColumnMetadata>asList()); // When updater.updateTableForEntity(session, meta, tableMeta); // Then verify(session, Mockito.times(2)).execute(stringCaptor.capture()); final List<String> updates = stringCaptor.getAllValues(); assertThat(updates.get(0)).isEqualTo("\n\tALTER TABLE tableName ADD longcol bigint"); assertThat(updates.get(1)).isEqualTo("\n\tCREATE INDEX long_index ON tableName(longcol)"); }
protected PropertyMeta parseCounterProperty(PropertyParsingContext context) { log.debug( "Parsing property {} as counter property of entity class {}", context.getCurrentPropertyName(), context.getCurrentEntityClass().getCanonicalName()); Class<?> entityClass = context.getCurrentEntityClass(); Field field = context.getCurrentField(); Method[] accessors = entityIntrospector.findAccessors(entityClass, field); PropertyType type = PropertyType.COUNTER; CounterProperties counterProperties = new CounterProperties(context.getCurrentEntityClass().getCanonicalName()); PropertyMeta propertyMeta = factory() .objectMapper(context.getCurrentObjectMapper()) .type(type) .propertyName(context.getCurrentPropertyName()) .entityClassName(context.getCurrentEntityClass().getCanonicalName()) .accessors(accessors) .field(field) .counterProperties(counterProperties) .consistencyLevels(context.getCurrentConsistencyLevels()) .build(Void.class, field.getType()); context.hasSimpleCounterType(); context.getCounterMetas().add(propertyMeta); if (context.isCustomConsistencyLevels()) { parseSimpleCounterConsistencyLevel(context, propertyMeta); } log.trace( "Built simple property meta for property {} of entity class {} : {}", propertyMeta.getPropertyName(), context.getCurrentEntityClass().getCanonicalName(), propertyMeta); return propertyMeta; }
private void parseSimpleCounterConsistencyLevel( PropertyParsingContext context, PropertyMeta propertyMeta) { log.trace("Parse custom consistency levels for counter property {}", propertyMeta); Pair<ConsistencyLevel, ConsistencyLevel> consistencyLevels = findConsistencyLevels(context.getCurrentField(), context.getDefaultConsistencyLevels()); validator.validateConsistencyLevelForCounter(context, consistencyLevels); log.trace("Found custom consistency levels : {}", consistencyLevels); propertyMeta.setConsistencyLevels(consistencyLevels); }
protected <K, V> PropertyMeta parseMapProperty(PropertyParsingContext context) { log.debug( "Parsing property {} as map property of entity class {}", context.getCurrentPropertyName(), context.getCurrentEntityClass().getCanonicalName()); Class<?> entityClass = context.getCurrentEntityClass(); Field field = context.getCurrentField(); boolean timeUUID = isTimeUUID(context, field); validator.validateMapGenerics(field, entityClass); Pair<Class<K>, Class<V>> types = determineMapGenericTypes(field); Class<K> keyClass = types.left; Class<V> valueClass = types.right; Method[] accessors = entityIntrospector.findAccessors(entityClass, field); PropertyType type = MAP; PropertyMeta mapMeta = factory() .objectMapper(context.getCurrentObjectMapper()) .type(type) .propertyName(context.getCurrentPropertyName()) .entityClassName(context.getCurrentEntityClass().getCanonicalName()) .consistencyLevels(context.getCurrentConsistencyLevels()) .accessors(accessors) .field(field) .timeuuid(timeUUID) .build(keyClass, valueClass); log.trace( "Built map property meta for property {} of entity class {} : {}", mapMeta.getPropertyName(), context.getCurrentEntityClass().getCanonicalName(), mapMeta); return mapMeta; }
public PropertyMeta parse(PropertyParsingContext context) { log.debug( "Parsing property {} of entity class {}", context.getCurrentPropertyName(), context.getCurrentEntityClass().getCanonicalName()); Field field = context.getCurrentField(); inferPropertyName(context); context.setCustomConsistencyLevels(hasConsistencyAnnotation(context.getCurrentField())); validator.validateNoDuplicate(context); validator.validateIndexIfSet(context); Class<?> fieldType = field.getType(); PropertyMeta propertyMeta; if (List.class.isAssignableFrom(fieldType)) { propertyMeta = parseListProperty(context); } else if (Set.class.isAssignableFrom(fieldType)) { propertyMeta = parseSetProperty(context); } else if (Map.class.isAssignableFrom(fieldType)) { propertyMeta = parseMapProperty(context); } else if (Counter.class.isAssignableFrom(fieldType)) { propertyMeta = parseCounterProperty(context); } else if (context.isEmbeddedId()) { propertyMeta = parseEmbeddedId(context); } else if (context.isPrimaryKey()) { propertyMeta = parseId(context); } else { propertyMeta = parseSimpleProperty(context); String indexName = getIndexName(field); if (indexName != null) { propertyMeta.setIndexProperties(new IndexProperties(indexName)); } } context.getPropertyMetas().put(context.getCurrentPropertyName(), propertyMeta); return propertyMeta; }
protected PropertyMeta parseEmbeddedId(PropertyParsingContext context) { log.debug( "Parsing property {} as embedded id of entity class {}", context.getCurrentPropertyName(), context.getCurrentEntityClass().getCanonicalName()); Class<?> entityClass = context.getCurrentEntityClass(); Field field = context.getCurrentField(); EmbeddedId embeddedId = field.getAnnotation(EmbeddedId.class); String propertyName = StringUtils.isNotBlank(embeddedId.name()) ? embeddedId.name() : context.getCurrentPropertyName(); Method[] accessors = entityIntrospector.findAccessors(entityClass, field); PropertyType type = EMBEDDED_ID; EmbeddedIdProperties embeddedIdProperties = extractEmbeddedIdProperties(field.getType()); PropertyMeta propertyMeta = factory() .objectMapper(context.getCurrentObjectMapper()) .type(type) .propertyName(propertyName) .embeddedIdProperties(embeddedIdProperties) .entityClassName(context.getCurrentEntityClass().getCanonicalName()) .accessors(accessors) .field(field) .consistencyLevels(context.getCurrentConsistencyLevels()) .build(Void.class, field.getType()); log.trace( "Built embedded id property meta for property {} of entity class {} : {}", propertyMeta.getPropertyName(), context.getCurrentEntityClass().getCanonicalName(), propertyMeta); return propertyMeta; }
public <V> PropertyMeta parseSetProperty(PropertyParsingContext context) { log.debug( "Parsing property {} as set property of entity class {}", context.getCurrentPropertyName(), context.getCurrentEntityClass().getCanonicalName()); Class<?> entityClass = context.getCurrentEntityClass(); Field field = context.getCurrentField(); boolean timeUUID = isTimeUUID(context, field); Class<V> valueClass; Type genericType = field.getGenericType(); valueClass = inferValueClassForListOrSet(genericType, entityClass); Method[] accessors = entityIntrospector.findAccessors(entityClass, field); PropertyType type = SET; PropertyMeta setMeta = factory() .objectMapper(context.getCurrentObjectMapper()) .type(type) .propertyName(context.getCurrentPropertyName()) .entityClassName(context.getCurrentEntityClass().getCanonicalName()) .consistencyLevels(context.getCurrentConsistencyLevels()) .accessors(accessors) .field(field) .timeuuid(timeUUID) .build(Void.class, valueClass); log.trace( "Built set property meta for property {} of entity class {} : {}", setMeta.getPropertyName(), context.getCurrentEntityClass().getCanonicalName(), setMeta); return setMeta; }
private void validateCollectionAndMapColumn(TableMetadata tableMetadata, PropertyMeta pm) { log.debug("Validate existing collection/map column {} from table {}"); String columnName = pm.getPropertyName().toLowerCase(); String tableName = tableMetadata.getName(); ColumnMetadata columnMetadata = tableMetadata.getColumn(columnName); Validator.validateTableTrue( columnMetadata != null, "Cannot find column '%s' in the table '%s'", columnName, tableName); Name realType = columnMetadata.getType().getName(); Name expectedValueType = toCQLType(pm.getValueClassForTableCreation()); switch (pm.type()) { case LIST: Validator.validateTableTrue( realType == Name.LIST, "Column '%s' of table '%s' of type '%s' should be of type '%s' indeed", columnName, tableName, realType, Name.LIST); Name realListValueType = columnMetadata.getType().getTypeArguments().get(0).getName(); Validator.validateTableTrue( realListValueType == expectedValueType, "Column '%s' of table '%s' of type 'List<%s>' should be of type 'List<%s>' indeed", columnName, tableName, realListValueType, expectedValueType); break; case SET: Validator.validateTableTrue( realType == Name.SET, "Column '%s' of table '%s' of type '%s' should be of type '%s' indeed", columnName, tableName, realType, Name.SET); Name realSetValueType = columnMetadata.getType().getTypeArguments().get(0).getName(); Validator.validateTableTrue( realSetValueType == expectedValueType, "Column '%s' of table '%s' of type 'Set<%s>' should be of type 'Set<%s>' indeed", columnName, tableName, realSetValueType, expectedValueType); break; case MAP: Validator.validateTableTrue( realType == Name.MAP, "Column '%s' of table '%s' of type '%s' should be of type '%s' indeed", columnName, tableName, realType, Name.MAP); Name expectedMapKeyType = toCQLType(pm.getKeyClass()); Name realMapKeyType = columnMetadata.getType().getTypeArguments().get(0).getName(); Name realMapValueType = columnMetadata.getType().getTypeArguments().get(1).getName(); Validator.validateTableTrue( realMapKeyType == expectedMapKeyType, "Column %s' of table '%s' of type 'Map<%s,?>' should be of type 'Map<%s,?>' indeed", columnName, tableName, realMapKeyType, expectedMapKeyType); Validator.validateTableTrue( realMapValueType == expectedValueType, "Column '%s' of table '%s' of type 'Map<?,%s>' should be of type 'Map<?,%s>' indeed", columnName, tableName, realMapValueType, expectedValueType); break; default: break; } }