I have a some classes which I need to serialize in two different ways: first- "basic" fields, and the second- some other fields.
e.g. a User class which I sometimes need to serialize just the "first name" and "last name" fields, and sometimes I need to serialize the "id" and "email"
fields as well.
The best way I found to do this so far is mark the basic fields with the [DataMember] attribute, and let .NET do the serializing for me, and for the rest
mark them with a customize attribute and do the serialization myself.
This solution proved to be very costly:
I first sirialize the basic attributes (as mentioned, .NET does that for me)
Then I get the property names of the fields marked with the custom attribute (using reflection namespace),
Then I try to get the those fields and their values from the object, and add their serialization to the basic serialization (not very successfully so far).....
Question is:
Is there a better way? preferbly by which .NET will do the rest of the work for me, and if not, at least one by which I don't need to go through all the
object's fields, find the relevant ones and serialize them myself..
Thank you all..
Oren,
Are you having to run these operations 1000x or more per minute? If not, all but the clumsiest of solutions will not be too costly. For exmample, if you need to do it like this, working from 2 objects is probably just fine. if you haven't actually run real timing comparisons, there's a huge chance you're wrong about what's expensive and what isn't.
But if you want to do it like this anyway, here is a solution that will only take 1% more time.
have an object, e.g., Core, for the subset, and Full for the whole thing
in the constructor of Full, instantiate a private instance of Core (composition pattern sort of). This has insignificant overhead.
Full will not have private member variables for the Core members. Full's setters and getters of the core data will refer to the private instance of Core. So no overhead.
Now you have 2 objects to serialize.
Related
C# 9 introduces record reference types. A record provides some synthesized methods like copy constructor, clone operation, hash codes calculation and comparison/equality operations. It seems to me convenient to use records instead of classes in general. Are there reasons no to do so?
It seems to me that currently Visual Studio as an editor does not support records as well as classes but this will probably change in the future.
Firstly, be aware that if it's possible for a class to contain circular references (which is true for most mutable classes) then many of the auto generated record members can StackOverflow. So that's a pretty good reason to not use records for everything.
So when should you use a record?
Use a record when an instance of a class is entirely defined by the public data it contains, and has no unique identity of it's own.
This means that the record is basically just an immutable bag of data. I don't really care about that particular instance of the record at all, other than that it provides a convenient way of grouping related bits of data together.
Why?
Consider the members a record generates:
Value Equality
Two instances of a record are considered equal if they have the same data (by default: if all fields are the same).
This is appropriate for classes with no behavior, which are just used as immutable bags of data. However this is rarely the case for classes which are mutable, or have behavior.
For example if a class is mutable, then two instances which happen to contain the same data shouldn't be considered equal, as that would imply that updating one would update the other, which is obviously false. Instead you should use reference equality for such objects.
Meanwhile if a class is an abstraction providing a service you have to think more carefully about what equality means, or if it's even relevant to your class. For example imagine a Crawler class which can crawl websites and return a list of pages. What would equality mean for such a class? You'd rarely have two instances of a Crawler, and if you did, why would you compare them?
with blocks
with blocks provides a convenient way to copy an object and update specific fields. However this is always safe if the object has no identity, as copying it doesn't lose any information. Copying a mutable class loses the identity of the original object, as updating the copy won't update the original. As such you have to consider whether this really makes sense for your class.
ToString
The generated ToString prints out the values of all public properties. If your class is entirely defined by the properties it contains, then this makes a lot of sense. However if your class is not, then that's not necessarily the information you are interested in. A Crawler for example may have no public fields at all, but the private fields are likely to be highly relevant to its behavior. You'll probably want to define ToString yourself for such classes.
All properties of a record are per default public
All properties of a record are per default immutable
By default, I mean when using the simple record definition syntax.
Also, records can only derive from records and you cannot derive a regular class from a record.
Consider you are doing some integration testing, you are storing some bigger entity into db, and then read it back and would like to compare it. Obviously it has some associations as well, but that's just a cherry on top of very unpleasant cake. How do you compare those entities? I saw lot of incorrect ideas and feel, that this has to be written manually. How you guys do that?
Issues:
you cannot use equals/hashcode: these are for natural Id.
you cannot use subclass with fixed equals, as that would test different class and can give wrong results when persisting data as data are handled differently in persistence context.
lot of fields: you don't want to type all comparisons by hand. You want reflection.
#Temporal annotations: you cannot use trivial "reflection equals" approaches, because #Temporal(TIMESTAMP) java.util.Date <> java.sql.Date
associations: typical entity you would like to have properly tested will have several associations, thus tool/approach ideally should support deep comparison. Also cycles in object graph can ruin the fun.
Best solution what I found:
don't use transmogrifying data types (like Date) in JPA entities.
all associations should be initialized in entity, because null <> empty list.
calculate externaly toString via say ReflectionToStringBuilder, and compare those. Reason for that is to allow entity to have its toString, tests should not depend that someone does not change something. Theoretically, toString can be deep, but commons recursive toStringStyle includes object identifier, which ruins it.
I though, that I could use json format to string, but commons support that only for shallow toString, Jackson (without further instructions on entity) fails on cycles over associations
Alternative solution would be actually declaring subclasses with generated id (say lombok) and use some automatic mapping tool (say remondis mapper), with option to overcome differences in Dates/collections.
But I'm listening. Does anyone posses better solution?
I am quite new to JPA. I have a particular repository that uses the keys that have parts that are set by the caller and some values that are automatically calculated using these values. There is a need for this :)
Since the keys and entities are simple Java classes it appears to me that I need to put my code that modifies the key (or substitutes it with an internal one with additional values) is the repository implementation. However I do not think that copying the code from SimpleJpaRepository to my custom repositories is a good idea...I think that something should be possible with the entity manager. Basically what I need is proxy that gets called every time something like find() or delete() is called, takes the entity, updates its key, passes the call over to the real repository implementation.
Could someone point me to the right direction or an example that does something similar?
Thanks!
In JPA, you have a bunch of events for this, just chose the one that suits you best. It looks like you are looking for #PrePersist.
http://www.objectdb.com/api/java/jpa/annotations/callback
That said, if the data of these fields is calculated based only in the data of the other fields, it goes against database normalization. A more sensate approach would be make the calculated field #Transient and provide only the getters, that will calculate the values based in the persistent fields.
Any advice on how to store a simple custom config class in core data. Options would be I think:
Entity with a "key" and "value" attributes - perhaps different attributes to represent different possible types (e.g. Integer16, String etc)
Custom class type entity which specific attributes for each config item I want - only catch would be that you would only ever want have one record in this entity, but the benefits would be it should be more usable I think: e.g. for the "fontSize" config items it would just be once you get the 1st record back from core data: "configRecord.fontSize". No need to access via a key-value arrangement and then cast the result or whatever.
Comments?
If there would only ever be one of these, I am not sure why you would save this information in Core Data and not simply as NSUserDefaults. Don't get me wrong, I like Core Data a lot. But seems like a lot of overhead for what could be stored as a dictionary.
If you had many of these, then Core Data and your second option would enable easy searching, etc. But this is not the case.
In terms of "configRecord.fontSize" convenience, you could read in NSUserDefaults into your own custom class and provide getters/setters there - without resorting to Core Data.
Just my two cents worth ;-)
I've run with my options 2 which seems to work a treat - and lieu of any suggested disadvantages (which I haven't found yet)
The Liskov Substitution Principle (LSP) on Wikipedia
Say I have a Alien class with an numFingers attribute*. Occasionally, I need to pull the sum of the numFingers from the database, grouped by other field values. In these cases, I have no need to manipulate each record individually, but I do need access to a lot of their functionality -- be able to get attributes, perform some basic logic on them, etc. This may include data summed from thousands of records, so it makes little sense to instantiate thousands of Alien objects when the database query can do the work of summing for me.
I would like to make an extension class called AlienAggregate, whose attributes are set from the grouped & summed query. This class would allow me to call any of Alien's methods. The only difference between functionality of the two classes, is GetID(). The aggregate class has no ID, since its data has been derived from any number of records. Because of this, calling GetID() on AlienAggregate throws an exception.
Is this a violation of the Liskov Substitution Principle? Is there a better way to handle a call to GetID()? Is there a better way to design the relationship between the Alien and AlienAggregate classes?
*Actual names may have been changed just because I can.
I don't think you're violating LSP since the principle only applies when Alien is a subtype of AlienAggregate (or the other way around). There is no is a relationship here (more of an aggregation of Alien's as you've appropriately named them).
Instead, it sounds like both Alien, and AlienAggregate probably implement a LooksAlien Interface. The Alien class just has an additional method, GetID().
...just beware of the nefarious BeginInvasion method on AlienAggregate.