Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an easy way to configure auto json/xml serialization to cassandra text types [DATACASS-295] #466

Closed
spring-projects-issues opened this issue Jun 9, 2016 · 5 comments
Assignees
Labels
status: duplicate type: enhancement

Comments

@spring-projects-issues
Copy link

@spring-projects-issues spring-projects-issues commented Jun 9, 2016

Tomasz Szlek opened DATACASS-295 and commented

When create table model using annotations Spring data cassandra supports by default only basic column types like String, Date, UUID.
In many use cases developers decides to store json, xml files in one cassandra text column.
For such purposes in Cassandra 3.0 driver guys from Datastax introduced Custom codecs feature, see : Cassandra 3.0 driver release
It would be a nice feature to be able to declare custom column type using some annotation like @CompoundType and register a set of mapping described how to serialize it and deserialize particular object type to/from cassandra text column.
It could work similar to Spring property custom converter :
Spring Conversion service

Example how declaration might look:

@Table(value = "test")
public class SomeTable {

	@PrimaryKeyColumn(name = "pk", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
	private String pk;

	@ColumnCompoundType(value = "compound")
	private SomeJacksonAnnotatedClass object;

Then during save Spring could serialize SomeJacksonAnnotatedClass automatically to text and deserialize it during read.
What do you think about such feature ?


Issue Links:

  • DATACASS-283 Investigate on using Cassandra CodecRegistry for type mapping

  • DATACASS-280 Refactor Cassandra query execution and mapping to consolidate mapping
    ("is superseded by")

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Jun 9, 2016

Mark Paluch commented

Hi Tomasz Szlek

with the upgrade to Cassandra 3.0 we're investigating whether we can expose additional functionality by using CodecRegistry. This is useful for TupleValue and UDT types. Cassandra provides since 2.2 JSON support for retrieving/inserting data which gives some flexibility to represent incoming/outgoing data as JSON. Aren't UDT's the right choice to represent structured data within one field?

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Jun 9, 2016

Tomasz Szlek commented

Hi Mark,

You are right, UDT is a greate feature and I can use it as the data that I need to store are all json's. I will like it if you implement it in Spring Data Cassandra.
I was thinking about implementing something which gives more flexibility than UDT like CodecRegistry.
I see following advantages of CodecRegistry:

  • I can imagine that if you implement UDT then each UDT will need to have some annotations inside. In such scenario UDT won't work for some 3rd party libraries, even for java and time api types (for now people are using ConversionServiceFactoryBean but its not a friendly way to configure mapping).
  • UDT support json only so if someone is using some other types like xml, he would needs to write converter per each type.

Summarizing UDT is great and would handle most of the cases, but adding support for CodecRegistry could be a nice feature too.
I would be happy if Spring data cassandra will support at least one of these fetaure.

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Jul 5, 2016

Mark Paluch commented

Update on this one:

We added CustomConversions to Spring Data Cassandra. You can now register own converters to perform mapping on your own. See the following example how to map a Person type to String using Jackson:

	@Table
	static class Employee {

		@Id String id;

		Person person;
		List<Person> friends;
		Set<Person> people;
		// getter/setter omitted
	}

	@Data
	static class Person {

		String firstname;
		String lastname;
		// getter/setter omitted
	}

	static class PersonReadConverter implements Converter<String, Person> {

		public Person convert(String source) {

			if (StringUtils.hasText(source)) {
				try {
					return new ObjectMapper().readValue(source, Person.class);
				} catch (IOException e) {
					throw new IllegalStateException(e);
				}
			}

			return null;
		}
	}

	static class PersonWriteConverter implements Converter<Person, String> {

		public String convert(Person source) {

			try {
				return new ObjectMapper().writeValueAsString(source);
			} catch (IOException e) {
				throw new IllegalStateException(e);
			}
		}
	}

Converters can be registered using the Java Config by extending from AbstractCassandraConfiguration and overriding the CustomConversions customConversions() method

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Jul 28, 2016

Tomasz Szlek commented

Hi Mark, thank you very much for such a good work. It is very compact and elegant solution which do the trick

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Jul 28, 2016

Mark Paluch commented

Thanks for your feedback. I'll close this ticket as a duplicate of DATACASS-280. You can give that feature a try, we released Spring Data Cassandra 1.5.0 M1 yesterday. See http://projects.spring.io/spring-data-cassandra/ for details on how to integrate it in your build

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: duplicate type: enhancement
Projects
None yet
Development

No branches or pull requests

2 participants