#Transient variable is not serialized using jackson [duplicate] - java

We use JSON serialization with Jackson to expose internal state of the system for debugging properties.
By default jackson does not serialize transient fields - but I wish to serialize them as well.
How can I serialize these fields?
One way I know is to supply a getters for these fields - but I don't want to do that, as I have some getX methods that I don't want to be invoked ( for instance, there are some getters that change the objects state ).
I know I could create an annotation, but I really want to avoid it.
So my question is:
Is there a way to setup jackson to serialize all the objects fields? include transient ones.

My solution with Jackson 2.4.3:
private static final ObjectMapper mapper =
new ObjectMapper(){{
Hibernate4Module module = new Hibernate4Module();
module.disable(Hibernate4Module.Feature.USE_TRANSIENT_ANNOTATION);
registerModule(module);
}};

I don't think Jackson supports any type of configuration to enable it to serialize a transient field. There's an open issue to add that feature, but it's old and hasn't been addressed (as far as I can tell): http://jira.codehaus.org/browse/JACKSON-623
So my question is: Is there a way to setup jackson to serialize all
the objects fields? include transient ones.
So to answer your question, no.
Some other Java JSON tools, such as GSON do support a configuration option to serialize transient fields. If you can use another tool, you might look into that (for GSON, see: https://sites.google.com/site/gson/gson-user-guide).
To expand a little, you might try a different approach.
First, You shouldn't try to serialize a transient field. After all the definition of transient is "don't serialize this." Nevertheless I can think of a few specific situations where it might be necessary, or at least convenient (like when working with code you can't modify or such). Still, in 99% of cases, the answer is don't do that. Change the field so that it's not transient if you need to serialize it. If you have multiple contexts where you use the same field, and you want it serialized in one (JSON, for example), and not serialized in another (java.io, for example) then you should create a custom serializer for the case where you don't want it, rather than abuse the keyword.
Second, as to using a getter and having "some getters that change the objects state," you should try to avoid that too. That can lead to various unintended consequences. And, technically, that's not a getter, that's a setter. What I mean is, if it mutates state, you've got a mutator (setter) rather than accessor (getter), even if you name it following the "get" convention and return some stuff.

You can create a custom getter for that transient field and use #XmlElement attribute. It doesn´t matter the name of that getter.
For example:
public class Person {
#XmlTransient private String lastname;
#XmlElement(name="lastname")
public String getAnyNameOfMethod(){
return lastname;
}
}

Another way to let Jackson serialize property is to add #JsonProperty annotation above it.
I guess it's better approach cause you do not need to disable default behaviour for all #Transient fields, like in Gere's answer.

Related

Is it possible to map custom final classes in hibernate?

Suppose I have already made class which I wish to persist. I can't change it's code, i.e. can't put any annotations inside. Also, class is not following bean convention.
I.e. it is arbitrary complex class I wish to persist.
Is it possible to write some sort of custom serializer and deserializer (don't know how to name it) in Hibernate, so that I be able to read these classes as usual POJOs?
Hello the first question is can I map a "fina class" the answer to this question is YES as long as you dont use Hibernate Enchancing or some sort of instrumentation.
Now second question. Bean not following Bean Conventions. I guess this means no getters and setters. You can have Attribute level access so this is again not a problem.
Is it possible to write custom serializer in Hibernate. The answer here is NO. Why ? Because Hibernate is not about Serialization hibernate is about SQL. There is no strict requirement that a Hibernate Entity should be serialize-able.
Even though Hibernate does not enforce serialization. Can I still make my final class serialize-able even though it does not implement Serializable or Eternalizeable. Yes you need to wrap it into class implementing Serializable or Externalizeable and implement the doRead doWrite methods yourself.
Serialization to JSON or XML - this is not part of Hibernate neither is part of JPA. Serialization to these two formats is defined as part of the Jaxb and Jax-rs specifications.
Have a look at hibernate UserType and CompositeUserType, with the well known EnumUserType example
Enums are a bit like your needs : final class, no getters nor setters. They are not complex though, so you might need a CompositeUserType that allows to map several columns for one Type, rather that a UserType.
Then you would use it like that in your class :
public class MyClass {
#Id
private Long id;
#Type(type = "com...MyCompositeUserType")
private ComplexFinalClassNotPojo complexObject;
}

Serialize an object with no data in Jackson

Is it possible to serialize an object with no fields in Jackson using only annotations? When I attempt to serialize such an object with no annotations I get:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class [redacted].SubjectObjectFeatureExtractor and no properties discovered to create BeanSerializer
I have examined the list of Jackson annotations without seeing a way to annotate the class as having no serializable data. I tried putting #JsonCreator on the empty constructor (not expecting it to work, since it's a deserialization annotation), and I got the same error. There are no accessors or fields to put #JsonProperty on. Any ideas?
Update: The reason for this is that I have a list of objects which represent transformations which can be applied to a certain type of data. Some of these transformations are defined by parameters which needs to be serialized, but some of these are parameter-less (the data-less objects in question). I'd like to be able to serialize and deserialize a sequence of these transformations. Also, I'm using DefaultTyping.NON_FINAL so that the class name will be serialized.
Update: An example class would be
class ExtractSomeFeature implements FeatureExtractor<SomeOtherType> {
public void extractFeature(SomeOtherType obj, WeightedFeatureList output) {
// do stuff
}
}
I don't particularly care how the JSON for this looks like, as long as I can deserialize List<FeatureExtractor>s properly. My impression is that using default typing, the expected JSON would be something like:
['com.mycompany.foo.ExtractSomeFeature', {}]
Other sub-classes of FeatureExtractor would have real parameters, so they would presumably look something like:
[`com.mycompany.foo.SomeParameterizedFeature', {some actual JSON stuff in here}]
I think I could use #JsonValue on some toJSONString() method to return {}, but if possible I'd like to hide such hackery from end-users who will be creating FeatureExtractor sub-classes.
You have to configure your object mapper to support this case.
ObjectMapper objectMapper = ...
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
The documentation of this feature can be found here : Fail on empty beans
Feature that determines what happens when no accessors are found for a
type (and there are no annotations to indicate it is meant to be
serialized). If enabled (default), an exception is thrown to indicate
these as non-serializable types; if disabled, they are serialized as
empty Objects, i.e. without any properties.
The answer to disable SerializationFeature.FAIL_ON_EMPTY_BEANS is global, and you therefore might not wish to apply it.
The answer to add any serialisation annotation showed the correct (as in: the Javadoc of SerializationFeature.FAIL_ON_EMPTY_BEANS suggests it) way to fix it, but only with a hackish or an unrelated annotation.
By merely adding…
#JsonSerialize
… to my class (not even parenthesēs after it, lest alone arguments!) I was able to produce the same effect (as, again, indicated by the Javadoc of SerializationFeature.FAIL_ON_EMPTY_BEANS).
Adding the following annotation onto the class seems to solve the problem:
#JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.NONE)
Adding an unrelated annotated like
#JsonRootName("fred")
also seems to fix it. This seems to match the claim in the JIRA ticket that adding any Jackson annotation to the class will prevent the exception. However, it appears adding annotations within the class does not.
Not sure I get your question, but perhaps you want JsonInclude.Include.NON_DEFAULT, JsonInclude.Include.NON_NULL, or JsonInclude.Include. NON_EMPTY.

The better solution to extend DTO object (Java, Hibernate)

I use EmailAlert bean as DTO to get data by means of Hibernate.
So, my class contains only fields that I have in DB.
But in some cases I need additional fields to be in EmailAlert to hold intermediate data. For example "caption" field - will be calculated on java side depends of user locale, time, etc.
So, I have some variants to solve this issue.
Add additional property (ex: caption) to EmailAlert bean, but do not map it with any field of DB table.
Drawback: In this case we have to do not use "caption" property in hashCode() and equals() because as:
It really don't have a matter - field holds only intermediate data
I am not sure it not be a cause of problem with cache and Hibernate itself.
I think it is very ugly to have a property of class but do not use it in equals() and hashCode() methods.
Someone can be confusing in the future with this logic.
Extend EmailAlert as EmailAlertExt with adding of "caption" property. And constructor that takes EmailAlert as argument.
But in this case I am not sure underwater stones in case I will store EmailAlert as EmailAlertExt bean again into DB.
Extend EmailAlert as EmailAlertExt2 with adding of "caption" property and take a refference to the original object. In this case EmailAlertExt2 will behave as original EmailAlert, but with additional property we need. In case we save EmailAlert we could call getOriginalValue() of EmailAlertExt2 that will return refference to original object.
Drawback: too many coding :)
Guys, which of these solutions is better? May be someone have other proposals?
Use '#Transient' it won't map to db hibernate will ignore this field
Extending a model object just because you want to separate mapped vs non-mapped fields is not a good idea. A good guideline would be to ask yourself the question "What is the difference between an EmailAlert and an EmailAlertX, and can I clearly define the situations where I would use one over the other?". If you cannot answer that question cleanly, or if you realize that you will always be using your subclass over the parent class, that is a sure sign that the parent class should be abstract or that you have too many classes.
In your particular case, it would make more sense to have both the mapped, and non-mapped properties on the same class, and to mark the non-mapped properties so that your ORM provider does not try to process them. You can do this by annotating these properties as being #Transient.
public class EmailAlert implements Serializable {
#Id
private Long id;
#Column(name = "recipient")
private String recipient;
#Transient
private transient String caption;
// Constructor, Getters/Setters, etc
}
Also, with respect to to your comment on hashcode/equals methods. You do not and should not include every property of a Java Bean in these methods. Only include those properties that are:
required to uniquely identify the object
are (fairly) guaranteed to have the same value over the lifecycle of the object
It sounds like the EmailAlert object you need at the moment is a business object, because of the "intermediate data" and "calculated on java side" bits.
Maybe use the EmailAlertDto object to populate the fields of the EmailAlertBusiness and store the extra caption field and the methods in the business object.

Jackson deserialization specific getter turning off

What is the most simple way to tell the Jackson to not serialize a specific getter method? I only want to say explicit to one getter, because I have a custom, complex class, and all setter and getter should function, only one should not:
mapper.configure(SerializationConfig.Feature.AUTO_DETECT_GETTERS, true);
So this is not the proper way. I need to tell that I don't want to use the getter in this class:
public static class EventRow implements Serializable, Cloneable, GRSerializable {
public int x
public int y
public double z
public String eventKeyValuesPacked;
//This getter should not be used, because there is no explicit setter
//for this, and also no public... And it is only unpack
//EventKeyValuesPacked so it would be multiple data...
public KeyValue[] getEventKeyValues() {
KeyValue[] kvs = DA_EventKey.unpackKeyValues(eventKeyValuesPacked);
return kvs == null ? new KeyValue[0] : kvs;
}
}
Is there any annotation or SerializationConfig option to make invisible the getEventKeyValues() getter method?
What is the most simple way to tell the Jackson to not serialize a specific getter method
...
without annotation?
Without writing a customer serializer...
If directly annotating the field/property/getter/setter to be skipped is undesirable, another approach is to make use of the Jackson Mix-In feature.
Yet another approach for serialization only would be to make use of the Jackson JSON Views feature, though this too requires annotations in some capacity.
There is an annotation for this: #JsonIgnore.
#JsonIgnore
public KeyValue[] getEventKeyValues() {
...
If you don't want to use an annotation for this then you'll need to write a custom serializer.
I think this almost do it:
objectMapper.configure(DeserializationConfig.FAIL_ON_UNKNOWN_PROPERTIES,
false);
This may depend on Jackson version -- prior to 1.9, getters and setters were handled separately, so not auto-detecting getter would have been enough. But with 1.9 and beyond, setter/getter/field are all combined into logical property, which may allow Jackson to deduce existence of property from setter.
So what you probably need to do is to also disable setter detection. Other options already given would work as well, mix-in annotations being a common way to do this.
objectMapper.configure(SerializationConfig.Feature.AUTO_DETECT_GETTERS, false);

How do you exclude object property in GWT from serialization?

Is there a way to exclude primitive and Object properties within Serializable Object from GWT Serialization?
public class Provider implements Serializable{
public Provider() {
}
//Id like to exclude this property:
private String password;
//
private String address1;
private String address2;
private String companyName;
private String phone;
}
I was hoping for something like
special annotation
I think what you are looking for is #GwtTransient
#GwtTransient, an annotation that
tells GWT RPC to treat a field as if
it were marked with the Java transient
keyword, even though it's not.
This annotation means the same thing
as the transient keyword,
but it is ignored by all serialization
systems other than GWT's. Usually the
transient keyword should be used in
preference to this annotation.
However, for types used with multiple
serialization systems, it can be
useful.
Reference: #GwtTransient
Can't you just declare it transient?
transient private String password;
If you really want to avoid using the transient keyword, you might want to look into Custom Field Serializers.
On my last GWT project, I used them to serialize immutable classes, since GWT-RPC had limitations for those.
It's a poorly documented feature, and the best explanation I found at the time was not in the GWT documentation, but on this great wogwt wiki page. You may also find some examples in GWT's com.google.gwt.user.client.rpc.core package, since GWT uses a lot of those.
Please note that CustomFieldSerializers still have some issues, such as issue 2931 and issue 3315. Also, I don't like the way they are defined: instead of using static methods, it would have been better to let users implement a CustomFieldSerializer<T> interface. We would have gained type safety and inheritance. But this is a whole other debate, and the GWT compiler might actually mandate the use of those static methods for performance reasons (I haven't looked into it).
Still, it works, and it's good to have them in specific cases.
add transient to the field

Categories

Resources