JAXB marshalling one POJO property into another - java

I get POJO that I get from database:
#Entity
public class Application implements Serializable{
private static final long serialVersionUID = 1L;
#Id
private Integer id;
#Column(name = "XMLOTHERINFORMATION", columnDefinition="XMLType")
private String xmlOtherInformation;
...
I want somehow create a getter for transient property for retrive unmarshalled class. I think that marshall/unmarshall in getter each time it has called is bad idea because xmlOtherInformation may be large and I am afraid it makes performance worse. Also there is another issue I String property and XMLClass should be synchronized before persistance. Any ideas how to deal with that?

To reach synchronization between two data structures I can recommend two options :
1) Use one data type (POJO preferable) in all your application and transform it to XML when needed. At this point you know that you transforming latest state of object.
2) Create a wrapper class that will contain both version of data and manage them separately. This will avoid transformation each time when you need some data type but also will decrease your performance and will allocate more memory.
Any way you have to decide what to do depending on your task. If you know that data going to be changed very frequently but not read then you may operate with single object and transform it in into another state when needed. In other case, if you have very frequently read operation then would be better to contain both data types in memory but then update will took more time.

Related

Update one parameters of many of objects - the best way

I have a situation to deliver solution for functionality of update one property of many objects. The point is that is possible to update any property. For example
class Book {
private String name;
private Long number;
private LocalDate date;
private SomeEnum name;
private boolean someFlag;
}
Possible is to update only one field at a time, but each field is available to update.
Of course I can create new filter class with each field and send it with given parameter I'd like to update, but I thinking about more elegant solution. More generic.
I have to List get objects by ids from database, update and save all with updated field.
What do You think this could be done. Is possible to create filter class with one generic field depend on what variable user give to update? What is the best practice to do something like that ? What is you experience ?

Hibernate Bidirectional Mapping Results in Cycle when using converter for DTO

I've mapped the classes as follows:
#ManyToOne(fetch = FetchType.LAZY,cascade = CascadeType.ALL)
#JoinColumn(name = "CATEGORY_ITEMS_ID")
private CategoryItem categoryItem;
#OneToMany(mappedBy="categoryItem",cascade = CascadeType.ALL, orphanRemoval = true)
private List<CategoryRating> categoryRatingList;
But when I need to convert the table models to dto's I'm caught in a cycle as:
target.setCategoryRatingDtoList(categoryRatingConverter.convert(source.getCategoryRatingList()));
target.setCategoryItemDto(categoryItemConverter.convertToDto(source.getCategoryItem()));
both converters end up calling each other.
I need the result as:
List of CategoryItems, in which every CategoryItems object contains a list of associated CategoryRatings
How should I solve this problem? Maybe I'm using bidirectional mapping in the wrong sense. Anyhow, kindly provide your opinion and possible solutions for this problem
You have 3 options.
You could introduce a context and register objects to that context in their constructors. When another object is then in it's constructor it can receive an inflight list/object through that context and thus resolve the cycle this way.
Another option is to make the DTOs mutable and first instantiate the objects as well as register them into a context, before setting the state on the objects. This is similar to the first solution with the slight difference that the DTO class doesn't need to know about the context.
The third solution is that you avoid the cycle by using a simpler converter for e.g. CategoryRating within the CategoryItemConverter that only converts some data, but not the categoryRatings list.

Android Firestore limitations to custom object models

I am migrating my app to use Firebase Firestore, and one of my models is very complex (contains lists of other custom objects). Looking at the documentation, on how to commit a model object as a document, it looks like you simply create your model object with a public constructor, and getters and setters.
For example from the add data guide:
public class City {
private String name;
private String state;
private String country;
private boolean capital;
private long population;
private List<String> regions;
public City() {}
public City(String name, String state, String country, boolean capital, long population, List<String> regions) {
// getters/setters
}
Firestore automatically translates this to and from and document without any additional steps. You pass an instance to a DocumentReference.set(city) call, and retrieve it from a call to DocumentSnapshot.toObject(City.class)
How exactly does it serialize this to a document? Through reflection? It doesn't discuss any limitations. Basically, I'm left wondering if this will work on more complex models, and how complex. Will it work for a class with an ArrayList of custom objects?
Firestore automatically translates this to and from and document without any additional steps. How exactly does it serialize this to a document? Through reflection?
You're guessing right, through reflection. As also #Doug Stevenson mentioned in his comment, that's very common for systems as Firebase, to convert JSON data to POJO (Plain Old Java Object). Please also note that the setters are not required. If there is no setter for a JSON property, the Firebase client will set the value directly onto the field. A constructor-with-arguments is also not required. While both are idiomatic, there are good cases to have classes without them. Please also take a look at some informations regarding the existens fo the no-argument constructor.
It doesn't discuss any limitations.
Yes it does. The official documentation explains that the documents have limits. So there are some limits when it comes to how much data you can put into a document. According to the official documentation regarding usage and limits:
Maximum size for a document: 1 MiB (1,048,576 bytes)
As you can see, you are limited to 1 MiB total of data in a single document. When we are talking about storing text, you can store pretty much but as your array getts bigger (with custom objects), be careful about this limitation.
Please also note, that if you are storing large amount of data in arrays and those arrays should be updated by lots of users, there is another limitation that you need to take care of. So you are limited to 1 write per second on every document. So if you have a situation in which a lot of users al all trying to write/update data to the same documents all at once, you might start to see some of this writes to fail. So, be careful about this limitation too.
Will it work for a class with an ArrayList of custom objects?
It will work with any types of classes as long as are supported data type objects.
Basically, I'm left wondering if this will work on more complex models, and how complex.
It will work with any king of complex model as long as you are using the correct data types for your objects and your documents are within that 1 MIB limitation.

Firebase Java POJOs and local-only fields

Given the following POJO example which stores local fields applicable only to the app running right here, nobody else whom also use the Firebase data:
#IgnoreExtraProperties
public class DispatchModel {
private String isotimestamp;
private String date_time;
private String event_uuid;
//...
private String locallyCreatedValue;
//...constructor, getters, setters
}
Given my Firebase data has the first three fields stored in it, and the locallyCreatedValue is added to my POJO during app runtime, is there a way to automatically fetch all the locally added content from a POJO instance and apply to the new instance when an update from onChildChanged event happens?
As it is right now, I'll have to manually obtain all the local field values and set them on the new instance:
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
DispatchModel newModel = dataSnapshot.getValue(DispatchModel.class);
// get list index of expiring instance
// get instance of old item at list index
// index = ...
// old = ...
// repeat this for every local item :-/
newModel.setLocallyCreatedValue(old.getLocallyCreatedValue);
dispatchList.set(index, newModel);
}
I plan on having quite a few local fields, is this my only option? Are there any functions Firebase offers that makes their automatic object instantiation more friendly to my extras? I'm not keen on creating distinct POJOs to track the Firebase POJOs in parallel. That lends to data errors from decoupled data updates and careful schedules for execution.
If all of your locally created values are expressed as standard getters and setters in your POJO, you are either going to have to copy them manually, or write some fairly intense Java reflection code to inspect the class, somehow figure out which properties are local (annotation? inclusion/exclusion from a known list?) and should be copied over, then actually do that work. You will not be able to get this "for free" using some utility (unless there happens to be some third party library that has solved this specific problem, and I doubt it).
Consider instead maybe storing your locally created values as a Map, then simply copying that map wholesale between objects. But then you have unknown types for the values if they're all different.
Or rewrite your code in JavaScript, which has easy property enumeration. :-)

ATG JavaBean over RepositoryItem

I doesn't understand how to use repositoryItem in ATG. How do I need construct customized logic on it.
Do I need to create usual JavaBean over repositoryItem or I need to use it as is?
I will try to explain:
Logic on repositoryItem:
RepositoryItem store = getRepository().getItem(..);
String address = store.getPropertyValue(..);
Logic on JavaBean:
class StoreBean {
String address;
StoreBean(RepositoryItem store) {
address = store.getPropertyValue(..);
}
}
Then I can use StoreBean how I want, to get it fields(lazy load for them, for example).
What will be best practices in ATG?
It is a matter of preference.
What you do not get with RepositoryItem objects is strong type checking. You must either make assumptions about the type of RepositoryItem you are working with or you have to do manual checks in your code (see example below). Additionally, since the RepositoryItem properties are stored as a metadata, you have to know 1) the actual names of the properties from the XML repository descriptor and 2) you need to know the types, which requires type casting (Example: String firstName = (String) item.getProperty("firstName");) Here is an example of a validation to ensure the RepositoryItem object is of type "sku":
RepositoryItemDescriptor skuItemDescriptor = getCatalogTools().getCatalog().getItemDescriptor(getCatalogTools().getBaseSKUItemType());
if (!RepositoryUtils.isTypeOfItemDesc(itemDescriptor, skuItemDescriptor)) {
throw new IllegalArgumentException("RepositoryItem must be of type " + getCatalogTools().getBaseSKUItemType());
}
If you take the approach of not using "JavaBeans", then you are increasing the risk of having runtime errors in your application. My suggestion is that you have a healthy balance between using RepistoryItem objects and wrapper objects. For critical items you plan to use in a large amount of your code base, I suggest using a wrapper object.
I suggest that if you create wrapper objects, that for consistency, you follow the same design pattern that Oracle Commerce uses. For example, the "order" item is wrapped by OrderImpl and implements the ChangedProperties interface.
public class OrderImpl
extends CommerceIdentifierImpl
implements Order, ChangedProperties
http://docs.oracle.com/cd/E52191_03/Platform.11-1/apidoc/atg/commerce/order/OrderImpl.html
ATG out of box repository implementations do not use JavaBeans for the most part. One big disadvantage of using JavaBeans and lazy loading them into memory will be to lose many repository caching features and will increase your memory footprint. For instance you will not be able to monitor your cache statistic or invalidate cache periodically. You will also have overheads of instantiations when you have huge repotiroyitem result set from a query.
Instead you can also use DynamicBean which lets you refer to repository properties similar to java beans for instance Profile.city.
If you only want to wrap them so that developers don't accidentally parse them incorrectly, you can write a util class per repository for various types of ready write operations and centralize your type safety.

Categories

Resources