I've seen a lot of Kundera examples where the object being store is fairly simple. You have something like a Car.class and it contains a couple String variables maybe an int mapped using the #Column annotation. I've even seen some List, Set and Map variables as well as the cqlsh to create a column of those types.
What I haven't seen is a custom object I created within an object and how that would be represented in a Cassandra DB.
For example:
public Class ContainerShip {
#Column(name="container")
Container myContainer;
}
public Class Container {
#Column(name="containerName)
String containerName;
}
Could I store ContainerShip into Cassandra, using Kundera with em.persist(myShip)?
If I can what would the cqlsh for creating the "container" column look like?
You may embed a container object as an embeddable entity.
#Entity
public Class ContainerShip {
#Column(name="container")
#Embedded
Container myContainer;
}
#Embeddable
public Class Container {
#Column(name="containerName)
String containerName;
}
Related
I am unable to save child class data with the persistence of parent class using astyanax in cassandra.
I created the child object with all necessary data, but when I try to store that object, only values from the parent class is stored, not from child object.
Here is the sample Code not real:
#Entity
class Shape{
#Id
private String id;
#Column
private String name;
}
#Entity
class square extends Shape{
#column
private int width;
}
now to store I am using EntityManager of astyanax.
square s=new square();
s.setName("sqaure");
s.setWidth(100);
s.setId("1234");
EntityManager em= //initialization code
em.put(s);
after doing this only "name" and "id" is stored into database. not width.
The EntityManager requires the type of the entity via the withEntityType() method. This type is used to build an EntityMapper via reflection which then determines the fields to serialize. There is nothing in the Entity persistence documentation or examples that says Astyanax supports polymorphism. This is not a bug, just a feature that doesn't exist. You will need a type-specific EntityManager for each subtype of your base class.
I'm using the Azure Mobile Service for a Windows Phone 8 project.
I am trying to store complex types in my database and therefore use json.net's JsonConverter.
My data-class looks like this:
public class Data
{
...
[JsonConverter(typeof(MyConverter))]
public ComplexType SomeMember{get;set;}
...
}
That seems to work fine, but there is one problem:
I want to map the 'Data'-class to a database table with a different name, like 'data_something'
This can be achieved by using
[DataContract(Name="data_something")]
public class Dat
{
...
}
But then the Json.NET Annotations are ignored.
Is there a way to use Json.NET and specify the Table-Name separately?
Or perhaps another way to use Azure Mobile to get the right table even if the class name is not the same. (I'm currently using dataTable= MobileService.GetTable<Data>();)
You can use the [DataTable] attribute for that:
[DataTable("data_something")]
public class Data
{
[JsonConverter(typeof(MyConverter))]
public ComplexType SomeMember { get; set; }
// other members ommitted
}
For example,
#Column("body")
private String body;
That will create a column "body"
I'd want to be able to annotate such that I can create a composite column such as "body:foo".
There isn't any example for this purpose or even any indication that this is possible. Does anyone have any more knowledge about this?
I'm not entirely sure that this will work with the entity persister, but I would maybe play around with something like:
#Column()
#Serializer(MyCompositeSerializer.class)
private SomeEntity entity;
public class MyCompositeSerializer extends AnnotatedCompositeSerializer<SomeEntity> {
public MyCompositeSerializer() {
super(SomeEntity.class);
}
}
Take a look at how public class AnnotatedCompositeSerializer<T> extends AbstractSerializer<T> is implemented to get a feel for what you need to do if the above approach doesn't work.
I want to abstract the implementation of my Azure TableServiceEntities so that I have one entity, that will take an object, of any type, use the properties of that object as the properties in the TableServiceEntity.
so my base object would be like
public class SomeObject
{
[EntityAttribute(PartitionKey=true)]
public string OneProperty {get; set:}
[EntityAttribute(RowKey=true)]
public string TwoProperty {get; set;}
public string SomeOtherProperty {get;set;}
}
public class SomeEntity<T> : TableServiceEntity
{
public SomeEntity(T obj)
{
foreach (var propertyInfo in properties)
{
object[] attributes = propertyInfo.GetCustomAttributes(typeof (DataObjectAttributes), false);
foreach (var attribute in attributes)
{
DataObjectAttributes doa = (DataObjectAttributes) attribute;
if (doa.PartitionKey)
PartitionKey = propertyInfo.Name;
}
}
}
}
Then I could access the entity in the context like this
var objects =
(from entity in context.CreateQuery<SomeEntity>("SomeEntities") select entity);
var entityList = objects.ToList();
foreach (var obj in entityList)
{
var someObject = new SomeObject();
SomeObject.OneProperty = obj.OneProperty;
SomeObject.TwoProperty = obj.TwoProperty;
}
This doesn't seem like it should be that difficult, but I have a feeling I have been looking at too many possible solutions and have just managed to confuse myself.
Thanks for any pointers.
Take a look at Lokad Cloud O/C mapper I think the source code imitates what you're attempting, but has insightful rationale about its different approach to Azure table storage.
http://lokadcloud.codeplex.com/
I have written an alternate Azure table storage client in F#, Lucifure Stash, which supports many abstractions including persisting a dictionary object. Lucifure Stash also supports large data columns > 64K, arrays & lists, enumerations, out of the box serialization, user defined morphing, public and private properties and fields and more.
It is available free for personal use at http://www.lucifure.com or via NuGet.com.
What you are attempting to achieve, a single generic class for any entity, can be implemented in Lucifure Stash by using the [StashPool] attribute on a dictionary type.
I have written a blog post about the table storage context, entities by specifying the entity type. Maybe it can help you http://wblo.gs/a2G
It seems you still want to use concrete types. Thus, the SomeEntity is a bit redundant. Actually, TableServiceEntity is already an abstract class. You can derive SomeObject from TableServiceEntity. From my experience, this won’t introduce any issues to your scenario.
In addition, even with your custom SomeEntity, it is failed to remove the dependence on the concrete SomeObject class in your last piece of code anyway.
Best Regards,
Ming Xu.
My table:
create table MyTable (
Id int identity(1,1) not null,
MyStatus char(2) not null
)
insert into MyTable(MyStatus) select 'A'
Class and enum:
public class MyTable
{
public virtual int Id { get; set; }
public virtual MyTableStatus MyStatus { get; set; }
}
public enum MyTableStatus
{
A,
B
}
Mapping:
public MyTableMap()
{
Id(x => x.Id);
Map(x => x.MyStatus);
}
When I execute the following test, I get System.FormatException : Input string was not in a correct format...
[Test]
public void Blah()
{
MyTable myTable = Session.Get<MyTable>(1);
Assert.That(myTable.MyStatus, Is.EqualTo(MyTableStatus.A));
}
What is the right way to map an enum to it's string representation in the database?
Edit - I am writing my application on an existing database, which I cannot modify easily because it is used by other applications also. So some fields in the database (which I would like to represent as enums in my application) are of type int and some of type char(2).
You need to create a custom IUserType to convert an enum to its string representation and back. There's a good example in C# here and an example in VB.NET for working with enums here (scroll down to implementing IUserType).
Well as far as I am aware NHibernate stores enums as string only in the db by default. I think I know what the problem here is. The way you are creating the table is incorrect.
if you are using Nhibernate use it build configuration function to create the tables instead of creating the tables manually and then you will see that your enum is stored as string.
We use enums extensively in our app and it makes sense for us to store it as strings in the db. The reasons are simple if I add a new value to an enum tom then if default values are not set then my code and my data are tightly coupled which I definitely wouldnt want.
SimpleConfig.ExposeConfiguration(c => new SchemaExport(c).Create(false, true)).BuildConfiguration();
Also instead of using char for your string can you use varchar for the property.
After the update:
Cant you guys do some kind of manipulation before you store it in the database? Thus when you want to store the new char enums write a function that generates an int value for you and store this in the propertry and now save it or if you want to make it simple the function can have a switch case.
So what you do is you dont have a get on this property that is retrieved from the db instead you add a new property in the class Status that basically has the logic of getting the appropriate enum.
Do you think thats a good idea?
Hope this helps.