DATACASS-85 - Completed
Unit test on ordering and Verifier Fixed bug with CassandraPersistentPropertyComparator
This commit is contained in:
@@ -22,10 +22,10 @@ public enum CassandraPersistentPropertyComparator implements Comparator<Cassandr
|
||||
public int compare(CassandraPersistentProperty left, CassandraPersistentProperty right) {
|
||||
|
||||
if (left != null && right == null) {
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
if (left == null && right != null) {
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
if (left == null && right == null) {
|
||||
return 0;
|
||||
@@ -57,11 +57,11 @@ public enum CassandraPersistentPropertyComparator implements Comparator<Cassandr
|
||||
boolean rightIsKey = rightIsCompositePrimaryKey || rightIsPrimaryKey;
|
||||
|
||||
if (leftIsKey && !rightIsKey) {
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!leftIsKey && rightIsKey) {
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// else, neither property is a composite primary key nor a primary key; compare @Column annotations
|
||||
|
||||
@@ -109,6 +109,7 @@ public class DefaultCassandraPersistentEntityMetadataVerifier implements Cassand
|
||||
for (CassandraPersistentProperty p : primaryKeyColumns) {
|
||||
if (p.getField().getAnnotation(PrimaryKeyColumn.class).type() == PrimaryKeyType.PARTITIONED) {
|
||||
partitionKeyExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!partitionKeyExists) {
|
||||
@@ -121,7 +122,7 @@ public class DefaultCassandraPersistentEntityMetadataVerifier implements Cassand
|
||||
*/
|
||||
if (idProperties.size() > 0) {
|
||||
exceptions.add(new MappingException(
|
||||
"Annotations @Id and @PrimaryKey are invalid for type annoated as @PrimaryKeyClass"));
|
||||
"Annotations @Id and @PrimaryKey are invalid for type annotated with @PrimaryKeyClass"));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -136,14 +137,7 @@ public class DefaultCassandraPersistentEntityMetadataVerifier implements Cassand
|
||||
/*
|
||||
* Ensure PrimaryKeyClass is Serializable
|
||||
*/
|
||||
Class<?>[] interfaces = thisType.getInterfaces();
|
||||
boolean isTypeSerializable = false;
|
||||
for (Class<?> c : interfaces) {
|
||||
if (c.equals(Serializable.class)) {
|
||||
isTypeSerializable = true;
|
||||
}
|
||||
}
|
||||
if (!isTypeSerializable) {
|
||||
if (!Serializable.class.isAssignableFrom(thisType)) {
|
||||
exceptions.add(new MappingException("@PrimaryKeyClass must be Serializable"));
|
||||
}
|
||||
|
||||
@@ -163,7 +157,8 @@ public class DefaultCassandraPersistentEntityMetadataVerifier implements Cassand
|
||||
throw new NoSuchMethodException();
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
exceptions.add(new MappingException("@PrimaryKeyClass must override 'boolean equals(Object)' method"));
|
||||
exceptions.add(new MappingException(
|
||||
"@PrimaryKeyClass must override 'boolean equals(Object)' method and use all @PrimaryKeyColumn fields", e));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -175,8 +170,10 @@ public class DefaultCassandraPersistentEntityMetadataVerifier implements Cassand
|
||||
throw new NoSuchMethodException();
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
exceptions.add(new MappingException("@PrimaryKeyClass must override 'int hashCode()' method"));
|
||||
exceptions.add(new MappingException(
|
||||
"@PrimaryKeyClass must override 'int hashCode()' method and use all @PrimaryKeyColumn fields", e));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -185,35 +182,29 @@ public class DefaultCassandraPersistentEntityMetadataVerifier implements Cassand
|
||||
if (isTable) {
|
||||
|
||||
/*
|
||||
* Ensure at least 1 PK
|
||||
* Ensure only one PK
|
||||
*/
|
||||
if (idProperties.size() == 0 && compositePrimaryKeys.size() == 0) {
|
||||
exceptions.add(new MappingException("@Table/@Persistent types must have at least 1 @PrimaryKey attribute"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure no more than 1 PK
|
||||
*/
|
||||
if (idProperties.size() + compositePrimaryKeys.size() > 1) {
|
||||
exceptions.add(new MappingException("@Table/@Persistent must have only 1 @PrimaryKey attribute"));
|
||||
int idPropertyCount = idProperties.size();
|
||||
if (idPropertyCount != 1) {
|
||||
exceptions.add(new MappingException(String.format(
|
||||
"@Table/@Persistent types must have only one @PrimaryKey attribute. Found %s.", idPropertyCount)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that Id is a supported Type. At the point there is only 1.
|
||||
*/
|
||||
if (idProperties.size() == 1) {
|
||||
Class<?> typeClass = idProperties.get(0).getType();
|
||||
if (!typeClass.isAnnotationPresent(PrimaryKeyClass.class)
|
||||
&& CassandraSimpleTypeHolder.getDataTypeFor(typeClass) == null) {
|
||||
exceptions.add(new MappingException("Fields annotated with @PrimaryKey must be simple CassandraTypes"));
|
||||
}
|
||||
Class<?> typeClass = idProperties.get(0).getType();
|
||||
if (!typeClass.isAnnotationPresent(PrimaryKeyClass.class)
|
||||
&& CassandraSimpleTypeHolder.getDataTypeFor(typeClass) == null) {
|
||||
exceptions.add(new MappingException(
|
||||
"Fields annotated with @PrimaryKey must be simple CassandraTypes or @PrimaryKeyClass type"));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine whether or not to throw Exception based on errors found
|
||||
*/
|
||||
if (exceptions.getErrorCount() > 0) {
|
||||
if (exceptions.getCount() > 0) {
|
||||
throw exceptions;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,7 @@ import org.springframework.data.mapping.model.MappingException;
|
||||
*/
|
||||
public class VerifierMappingExceptions extends MappingException {
|
||||
|
||||
Collection<String> messages = new LinkedList<String>();
|
||||
Collection<MappingException> errors = new LinkedList<MappingException>();
|
||||
Collection<MappingException> exceptions = new LinkedList<MappingException>();
|
||||
|
||||
/**
|
||||
* @param s
|
||||
@@ -43,16 +42,7 @@ public class VerifierMappingExceptions extends MappingException {
|
||||
* @param s
|
||||
*/
|
||||
public void add(MappingException e) {
|
||||
messages.add(e.getMessage());
|
||||
errors.add(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param s
|
||||
*/
|
||||
public void add(String s, MappingException e) {
|
||||
messages.add(s);
|
||||
errors.add(e);
|
||||
exceptions.add(e);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +51,7 @@ public class VerifierMappingExceptions extends MappingException {
|
||||
* @return The Collection of MappingException
|
||||
*/
|
||||
public Collection<MappingException> getMappingExceptions() {
|
||||
return errors;
|
||||
return exceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,7 +59,11 @@ public class VerifierMappingExceptions extends MappingException {
|
||||
*
|
||||
* @return The Collection of Messages
|
||||
*/
|
||||
public Collection<String> getMappingExceptionMessages() {
|
||||
public Collection<String> getMessages() {
|
||||
Collection<String> messages = new LinkedList<String>();
|
||||
for (MappingException e : exceptions) {
|
||||
messages.add(e.getMessage());
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
|
||||
@@ -78,15 +72,15 @@ public class VerifierMappingExceptions extends MappingException {
|
||||
*
|
||||
* @return Number of Errors present
|
||||
*/
|
||||
public int getErrorCount() {
|
||||
return errors.size();
|
||||
public int getCount() {
|
||||
return exceptions.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (String s : messages) {
|
||||
builder.append(s).append("\n");
|
||||
for (MappingException e : exceptions) {
|
||||
builder.append(e.getMessage()).append("\n");
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or 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 org.springframework.data.cassandra.test.unit;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.cassandra.core.PrimaryKeyType;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.PrimaryKey;
|
||||
import org.springframework.data.cassandra.mapping.PrimaryKeyClass;
|
||||
import org.springframework.data.cassandra.mapping.PrimaryKeyColumn;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
|
||||
/**
|
||||
* @author David Webb
|
||||
*
|
||||
*/
|
||||
public class BasicCassandraPersistentEntityOrderPropertiesTest {
|
||||
|
||||
private List<CassandraPersistentProperty> expected;
|
||||
private DefaultCassandraMappingContext mappingContext = new DefaultCassandraMappingContext();
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompositeKeyPropertyOrder() {
|
||||
|
||||
CassandraPersistentEntity<?> entity = mappingContext.getPersistentEntity(CompositePK.class);
|
||||
|
||||
expected = new LinkedList<CassandraPersistentProperty>();
|
||||
expected.add(entity.getPersistentProperty("key0"));
|
||||
expected.add(entity.getPersistentProperty("key1"));
|
||||
expected.add(entity.getPersistentProperty("key2"));
|
||||
|
||||
final List<CassandraPersistentProperty> actual = new LinkedList<CassandraPersistentProperty>();
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty persistentProperty) {
|
||||
actual.add(persistentProperty);
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(expected, actual);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTablePropertyOrder() {
|
||||
|
||||
CassandraPersistentEntity<?> entity = mappingContext.getPersistentEntity(CompositeKeyEntity.class);
|
||||
|
||||
expected = new LinkedList<CassandraPersistentProperty>();
|
||||
expected.add(entity.getPersistentProperty("key"));
|
||||
expected.add(entity.getPersistentProperty("attribute"));
|
||||
expected.add(entity.getPersistentProperty("text"));
|
||||
|
||||
final List<CassandraPersistentProperty> actual = new LinkedList<CassandraPersistentProperty>();
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty persistentProperty) {
|
||||
actual.add(persistentProperty);
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(expected, actual);
|
||||
|
||||
}
|
||||
|
||||
@Table
|
||||
static class CompositeKeyEntity {
|
||||
|
||||
@PrimaryKey
|
||||
private CompositePK key;
|
||||
|
||||
private String attribute;
|
||||
|
||||
private String text;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This is intentionally using dumb ordinals
|
||||
*/
|
||||
@PrimaryKeyClass
|
||||
static class CompositePK implements Serializable {
|
||||
|
||||
@PrimaryKeyColumn(ordinal = 2, type = PrimaryKeyType.PARTITIONED)
|
||||
private String key0;
|
||||
|
||||
@PrimaryKeyColumn(ordinal = 0)
|
||||
private String key1;
|
||||
|
||||
@PrimaryKeyColumn(ordinal = 1)
|
||||
private String key2;
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((key0 == null) ? 0 : key0.hashCode());
|
||||
result = prime * result + ((key1 == null) ? 0 : key1.hashCode());
|
||||
result = prime * result + ((key2 == null) ? 0 : key2.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
CompositePK other = (CompositePK) obj;
|
||||
if (key0 == null) {
|
||||
if (other.key0 != null)
|
||||
return false;
|
||||
} else if (!key0.equals(other.key0))
|
||||
return false;
|
||||
if (key1 == null) {
|
||||
if (other.key1 != null)
|
||||
return false;
|
||||
} else if (!key1.equals(other.key1))
|
||||
return false;
|
||||
if (key2 == null) {
|
||||
if (other.key2 != null)
|
||||
return false;
|
||||
} else if (!key2.equals(other.key2))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Table
|
||||
static class SimpleKeyEntity {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user