Cache data from MaterializedViews under their parent name. Add some relationship constraints that can decorate getters in model classes and be used in some cases to better cache data.
This commit is contained in:
parent
fe47531984
commit
a79e7dacf1
12 changed files with 337 additions and 9 deletions
|
@ -45,6 +45,7 @@ public class CacheUtil {
|
|||
}
|
||||
|
||||
public static Object merge(Object to, Object from) {
|
||||
// TODO(gburd): do a proper merge given that materialized views are cached with their table name
|
||||
if (to == from) {
|
||||
return to;
|
||||
} else {
|
||||
|
|
|
@ -156,6 +156,8 @@ public final class InsertOperation<T> extends AbstractOperation<T, InsertOperati
|
|||
insert.value(t._1.getColumnName(), t._2);
|
||||
});
|
||||
|
||||
//TODO(gburd): IF NOT EXISTS when @Constraints.Relationship is 1:1 or 1:m
|
||||
|
||||
if (this.ttl != null) {
|
||||
insert.using(QueryBuilder.ttl(this.ttl[0]));
|
||||
}
|
||||
|
|
|
@ -114,7 +114,13 @@ public final class HelenusMappingEntity implements HelenusEntity {
|
|||
|
||||
List<HelenusProperty> primaryKeyProperties = new ArrayList<>();
|
||||
ImmutableList.Builder<Facet> facetsBuilder = ImmutableList.builder();
|
||||
facetsBuilder.add(new Facet("table", name.toCql()).setFixed());
|
||||
if (iface.getDeclaredAnnotation(MaterializedView.class) == null) {
|
||||
facetsBuilder.add(new Facet("table", name.toCql()).setFixed());
|
||||
} else {
|
||||
facetsBuilder.add(
|
||||
new Facet("table", Helenus.entity(iface.getInterfaces()[0]).getName().toCql())
|
||||
.setFixed());
|
||||
}
|
||||
for (HelenusProperty prop : orderedProps) {
|
||||
switch (prop.getColumnType()) {
|
||||
case PARTITION_KEY:
|
||||
|
@ -130,7 +136,7 @@ public final class HelenusMappingEntity implements HelenusEntity {
|
|||
MappingUtil.getValidators(prop.getGetterMethod())) {
|
||||
if (constraint.getClass().isAssignableFrom(DistinctValidator.class)) {
|
||||
DistinctValidator validator = (DistinctValidator) constraint;
|
||||
String[] values = validator.value();
|
||||
String[] values = validator.constraintAnnotation.value();
|
||||
UnboundFacet facet;
|
||||
if (values != null && values.length >= 1 && !(StringUtils.isBlank(values[0]))) {
|
||||
List<HelenusProperty> props = new ArrayList<HelenusProperty>(values.length + 1);
|
||||
|
|
|
@ -235,4 +235,96 @@ public final class Constraints {
|
|||
*/
|
||||
String[] value() default "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Distinct annotation is used to signal, but not ensure that a value should be distinct in the
|
||||
* database.
|
||||
*
|
||||
* <p>Can be used only for @java.lang.CharSequence
|
||||
*
|
||||
* <p>It does not have effect on selects and data retrieval operations
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
||||
@Constraint(validatedBy = OneToOneRelationshipValidator.class)
|
||||
public @interface OneToOne {
|
||||
|
||||
/**
|
||||
* User defined list of properties that combine with this one to result in a distinct
|
||||
* combination in the table.
|
||||
*
|
||||
* @return Java
|
||||
*/
|
||||
String[] value() default "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Distinct annotation is used to signal, but not ensure that a value should be distinct in the
|
||||
* database.
|
||||
*
|
||||
* <p>Can be used only for @java.lang.CharSequence
|
||||
*
|
||||
* <p>It does not have effect on selects and data retrieval operations
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
||||
@Constraint(validatedBy = OneToManyRelationshipValidator.class)
|
||||
public @interface OneToMany {
|
||||
|
||||
/**
|
||||
* User defined list of properties that combine with this one to result in a distinct
|
||||
* combination in the table.
|
||||
*
|
||||
* @return Java
|
||||
*/
|
||||
String[] value() default "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Distinct annotation is used to signal, but not ensure that a value should be distinct in the
|
||||
* database.
|
||||
*
|
||||
* <p>Can be used only for @java.lang.CharSequence
|
||||
*
|
||||
* <p>It does not have effect on selects and data retrieval operations
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
||||
@Constraint(validatedBy = ManyToOneRelationshipValidator.class)
|
||||
public @interface ManyToOne {
|
||||
|
||||
/**
|
||||
* User defined list of properties that combine with this one to result in a distinct
|
||||
* combination in the table.
|
||||
*
|
||||
* @return Java
|
||||
*/
|
||||
String[] value() default "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Distinct annotation is used to signal, but not ensure that a value should be distinct in the
|
||||
* database.
|
||||
*
|
||||
* <p>Can be used only for @java.lang.CharSequence
|
||||
*
|
||||
* <p>It does not have effect on selects and data retrieval operations
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
||||
@Constraint(validatedBy = ManyToManyRelationshipValidator.class)
|
||||
public @interface ManyToMany {
|
||||
|
||||
/**
|
||||
* User defined list of properties that combine with this one to result in a distinct
|
||||
* combination in the table.
|
||||
*
|
||||
* @return Java
|
||||
*/
|
||||
String[] value() default "";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Helenus Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.helenus.mapping.validator;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
|
||||
public abstract class AbstractConstraintValidator<A extends Annotation, T>
|
||||
implements ConstraintValidator<A, T> {
|
||||
|
||||
public A constraintAnnotation;
|
||||
|
||||
@Override
|
||||
public void initialize(A constraintAnnotation) {
|
||||
this.constraintAnnotation = constraintAnnotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract boolean isValid(T value, ConstraintValidatorContext context);
|
||||
}
|
|
@ -20,13 +20,12 @@ import javax.validation.ConstraintValidatorContext;
|
|||
import net.helenus.mapping.annotation.Constraints;
|
||||
|
||||
public final class DistinctValidator
|
||||
extends AbstractConstraintValidator<Constraints.Distinct, CharSequence>
|
||||
implements ConstraintValidator<Constraints.Distinct, CharSequence> {
|
||||
|
||||
private Constraints.Distinct annotation;
|
||||
|
||||
@Override
|
||||
public void initialize(Constraints.Distinct constraintAnnotation) {
|
||||
annotation = constraintAnnotation;
|
||||
super.initialize(constraintAnnotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -34,8 +33,4 @@ public final class DistinctValidator
|
|||
// TODO(gburd): check that the list contains valid property names.
|
||||
return true;
|
||||
}
|
||||
|
||||
public String[] value() {
|
||||
return annotation == null ? null : annotation.value();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Helenus Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.helenus.mapping.validator;
|
||||
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import net.helenus.mapping.annotation.Constraints;
|
||||
|
||||
public class ManyToManyRelationshipValidator extends RelationshipValidator<Constraints.ManyToMany> {
|
||||
|
||||
@Override
|
||||
public void initialize(Constraints.ManyToMany constraintAnnotation) {
|
||||
super.initialize(constraintAnnotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
|
||||
// TODO(gburd): check that the list contains valid property names.
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Helenus Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.helenus.mapping.validator;
|
||||
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import net.helenus.mapping.annotation.Constraints;
|
||||
|
||||
public class ManyToOneRelationshipValidator extends RelationshipValidator<Constraints.ManyToOne> {
|
||||
|
||||
@Override
|
||||
public void initialize(Constraints.ManyToOne constraintAnnotation) {
|
||||
super.initialize(constraintAnnotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
|
||||
// TODO(gburd): check that the list contains valid property names.
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Helenus Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.helenus.mapping.validator;
|
||||
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import net.helenus.mapping.annotation.Constraints;
|
||||
|
||||
public class OneToManyRelationshipValidator extends RelationshipValidator<Constraints.OneToMany> {
|
||||
|
||||
@Override
|
||||
public void initialize(Constraints.OneToMany constraintAnnotation) {
|
||||
super.initialize(constraintAnnotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
|
||||
// TODO(gburd): check that the list contains valid property names.
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Helenus Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.helenus.mapping.validator;
|
||||
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import net.helenus.mapping.annotation.Constraints;
|
||||
|
||||
public class OneToOneRelationshipValidator extends RelationshipValidator<Constraints.OneToOne> {
|
||||
|
||||
@Override
|
||||
public void initialize(Constraints.OneToOne constraintAnnotation) {
|
||||
super.initialize(constraintAnnotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
|
||||
// TODO(gburd): check that the list contains valid property names.
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Helenus Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.helenus.mapping.validator;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
|
||||
public abstract class RelationshipValidator<A extends Annotation>
|
||||
extends AbstractConstraintValidator<A, CharSequence>
|
||||
implements ConstraintValidator<A, CharSequence> {
|
||||
|
||||
@Override
|
||||
public void initialize(A constraintAnnotation) {
|
||||
super.initialize(constraintAnnotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -22,9 +22,12 @@ import java.text.SimpleDateFormat;
|
|||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import net.helenus.core.ConflictingUnitOfWorkException;
|
||||
import net.helenus.core.Helenus;
|
||||
import net.helenus.core.HelenusSession;
|
||||
import net.helenus.core.UnitOfWork;
|
||||
import net.helenus.test.integration.build.AbstractEmbeddedCassandraTest;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -78,6 +81,34 @@ public class MaterializedViewTest extends AbstractEmbeddedCassandraTest {
|
|||
.from(CyclistsByAge.class)
|
||||
.where(cyclist::age, eq(18))
|
||||
.allowFiltering()
|
||||
.single()
|
||||
.sync();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMvUnitOfWork()
|
||||
throws TimeoutException, ConflictingUnitOfWorkException, Exception {
|
||||
Cyclist c1, c2;
|
||||
|
||||
UnitOfWork uow = session.begin();
|
||||
c1 =
|
||||
session
|
||||
.<Cyclist>select(Cyclist.class)
|
||||
.from(CyclistsByAge.class)
|
||||
.where(cyclist::age, eq(18))
|
||||
.single()
|
||||
.sync(uow)
|
||||
.orElse(null);
|
||||
|
||||
c2 =
|
||||
session
|
||||
.<Cyclist>select(Cyclist.class)
|
||||
.from(CyclistsByAge.class)
|
||||
.where(cyclist::age, eq(18))
|
||||
.single()
|
||||
.sync(uow)
|
||||
.orElse(null);
|
||||
Assert.assertEquals(c1, c2);
|
||||
uow.commit();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue