Reputation: 26858
I am using Spring Data Cassandra 1.0.0. I have managed to persist and read back my entity. However, now I want to do a query that only returns 1 field of the entity.
This is what I have tried:
public Optional<DateTime> getTimeOfOldestIntervalTrafficDataMessage( MessageSource messageSource, IntegrationPeriod integrationPeriod, TrafficDataType trafficDataType )
{
Select select = QueryBuilder.select( "message_time" ).from( "messages", "data_message" );
select.where( QueryBuilder.eq( "message_source_id", messageSource.getId().getId() ) )
.and( QueryBuilder.eq( "data_type", trafficDataType.name() ) )
.and( QueryBuilder.eq( "integration_period", integrationPeriod.name() ) );
List<Date> result = cassandraOperations.select( select, Date.class );
if (result.size() > 0)
{
return Optional.of( new DateTime( FluentIterable.from( result ).toSortedSet( Ordering.natural() ).first() ) );
}
else
{
return Optional.absent();
}
}
cassandraOperations
is a CassandraTemplate
instance.
So I only select message_time
from the data_message
table. This is a timestamp
column, so I pass in a Date.class
to the select()
method, but this gives the following exception:
org.springframework.data.mapping.model.MappingException: No mapping metadata found for java.util.Date
at org.springframework.data.cassandra.convert.MappingCassandraConverter.readRow(MappingCassandraConverter.java:111)
at org.springframework.data.cassandra.convert.MappingCassandraConverter.read(MappingCassandraConverter.java:202)
at org.springframework.data.cassandra.core.CassandraConverterRowCallback.doWith(CassandraConverterRowCallback.java:47)
at org.springframework.data.cassandra.core.CassandraTemplate.select(CassandraTemplate.java:455)
at org.springframework.data.cassandra.core.CassandraTemplate.select(CassandraTemplate.java:253)
at com.mycomp.app.infrastructure.cassandra.CassandraMessageRepository.getTimeOfOldestIntervalTrafficDataMessage(CassandraMessageRepository.java:130)
How should I query for just 1 field?
PS: If you would know a more performant way to do this query, I would be happy to hear it also.
Upvotes: 5
Views: 5750
Reputation: 26858
Found out how to do it:
public Optional<DateTime> getTimeOfOldestIntervalTrafficDataMessage( MessageSource messageSource, IntegrationPeriod integrationPeriod, TrafficDataType trafficDataType )
{
Select select = QueryBuilder.select( "message_time" ).from( "messages", "data_message" );
select.where( QueryBuilder.eq( "message_source_id", messageSource.getId().getId() ) )
.and( QueryBuilder.eq( "traffic_data_type", trafficDataType.name() ) )
.and( QueryBuilder.eq( "integration_period", integrationPeriod.name() ) );
select.orderBy( QueryBuilder.asc( "message_time" ) );
select.limit( 1 );
Date date = m_cassandraOperations.queryForObject( select, Date.class );
if( date != null )
{
Optional<DateTime> result = Optional.of( new DateTime( date ) );
logger.debug( "oldest interval: {} ({}/{}/{})", result, messageSource.getName(), trafficDataType, integrationPeriod );
return result;
}
else
{
return Optional.absent();
}
}
queryForObject()
function is the way to go. I also used ordering and limit to make Cassandra do the work of finding what I need.
Upvotes: 6