Attribute in OrderEntryModel coming as null even though I have defined a default value as 0.0 in items.xml - shopping-cart

We are using hybris 6.7 version.
I have created a new attribute in AbstractOrderEntryModel and I have defined a default value for it in the items.xml as 0.00D since it is a double type.
Now when I login to the storefront and add items to cart, it is working as expected. But when I login to a user who already has an active cart to him, it throws nullpointer. I did not handle the null pointer since I have declared its default value as 0.0 and it can't be null.
Now for resolving this, is it better to handle the null pointer or to create a groovy script to update all the old and existing carts?
Thanks in advance.

Yes, you need to update old records. You can update old records with impex, groovy or db query.

Personally, I would update the existing records that have null values for the new attribute.
Handling the exception is also a possible approach, but it's slightly ugly, since you already know it's not supposed to be null.

As per good practice, we should update already existing AbstractOrderEntryModel by creating a simple data migration script via groovy, Impex, or DB query.
it's not recommended to use a null check at the code level because newly created entries will go to the model life cycle and initdefault interceptor will do the job as you have already defined the default values.

Related

How to find out whether default value is used for Datastore ndb property?

Let's say we have a model like this:
class UserConfig(ndb.Model):
name = ndb.StringProperty()
email_subscriber = ndb.BooleanProperty(default=True)
Let's assume email_subscriber was set to default True by mistake and we want to fix that mistake and use default=False instead. I tried changing the value to default=False and that works fine for users created after that code is deployed, but that doesn't fix the problem for existing users.
Is there a way (e.g. some internal property which isn't documented in Datastore documentation), which would provide info whether given prop value was set explicitly by user or using the provided default.
I can write an upgrade which would set email_subscriber=False for all users, but I'm afraid some users might have intentionally checked this property in the app and wouldn't like to break their experience.
tl;dr: How can I determine if value in ndb object was set using the default for that property or was provided explicitly.
There is no way to know this. Once a value is set in the database there is no way to know which part of your code (ndb runs in your code from the database perspective) set the value.

Detect whether new Ember Data records have been changed by the user

When a new record is created using Ember Data, then get("isDirty") returns true. But as yet, the user has made no changes to the record, and we can discard it without losing any of the user's work.
Is there any official, supported way to detect this situation, where a record has been created but no properties have been set?
(There's in incomplete answer to this question for a much older version of Ember Data, before it was substantially overhauled. The didSetProperty function still exists in current releases, but it's undocumented. Still, it might be a possible path to a solution if nothing official can be found.)
Internally, the changed properties are tracked by the _attributes property. You could do a check of
record.get('isNew') && Ember.keys(record._attributes).length === 0
to see that it has just been created and nothing has been changed on it.
Note that this is not meant to be part of the external API, but I'm not aware of any external API to accomplish this.

How to manually set an object state to clean (saved) using ember-data

Explanation:
I'm using ember-data for a project of mine and I have a question that revolves around the possibility of dirtying an object and then setting its state to clean again on purpose - without commiting the changes. The scenario is this:
Say I've fetched an object via banana = App.Fruit.find('banana'); and it has a description of "Yellow fruit!". Using XHR long-polling (or WebSockets), I may receive an updated version of the object because of another user having changed the description to "A tasty yellow fruit!" at any given point in time after I fetched the original object.
Then, what I would like to do is to update the object to reflect the newly received data. For this, I've tried different approaches:
I've tried calling App.Store.load(App.Fruit, new_data);. First of all, this approach doesn't work and secondly, this is not really what I want. I could've made uncommitted changes to the object myself and in this case, it would be undesirable to just discard those (assuming the load() call would overwrite them).
I've tried looping through the new data, calling .set() - like so: banana.set('description', new_data.description); - in order to update the object properties with the new data (where applicable = not dirty). This works but it leaves the object in a dirtied state.
In order to make the object clean/updated again - and not have the adapter commit the changes! - I've taken a look at the states the object travels through. These are (at least):
Step 1: Initially, the object is in the rootState.loaded.saved state.
Step 2: Calling .set() on a property pushes it to the rootState.loaded.updated.uncommitted state.
Step 3: Calling App.store.commit(); returns the object to the rootState.loaded.saved state.
Therefore, I've tried to manually set the object state to saved after step 2 like so: banana.get('stateManager').goToState('saved');.
However, this doesn't work. The next time the store commits for any other reason, this maneuver produces an inFlightDirtyReasons is undefined error.
Question:
My question is: how can I manually change the state of a dirtied object back to clean (saved) again?
Solution for Ember Data 1.0.0-beta.7:
// changing to loaded.updated.inFlight, which has "didCommit"
record.send('willCommit');
// clear array of changed (dirty) model attributes
record.set('_attributes', {});
// changing to loaded.saved (hooks didCommit event in "inFlight" state)
record.send('didCommit');
I've searched the source code of Ember-data and I've found that loaded.saved state has a setup function that checks whether a model is clean, before setting "saved" state. If it is not clean, then it rejects a request to change state and returns to loaded.updated.uncommitted.
So you have to clean model._attributes array, which keeps attributes names and Ember will let you change state manually.
I know it isn't very good solution, because is needed to set private property of a model, but I've not found any other solutions yet.
Looking at ember-data the uncommitted state has a 'becameClean' event which consequently sets the record as loaded.saved.
This should do the trick
record.get('stateManager').send('becameClean');
Solution for Ember Data 2.6.1
record.send('pushedData');
set dirty record as loaded and saved
https://github.com/emberjs/data/blob/fec260a38c3f7227ffe17a3af09973ce2718acca/addon/-private/system/model/states.js#L250
It's an update to #Kamil-j's solution.
For Ember Data 2.0 which I am currently using I have to do the following:
record._internalModel.send('willCommit');
record._internalModel._attributes = {};
record._internalModel.send('didCommit');
As of 1.0.0.rc6.2....
This will move a model into the state of a model that has been saved.
record.get('stateManager').transitionTo('loaded.saved')
This will moves a model to a the state of a new model that has not been committed. Think new dirty model.
record.get('stateManager').transitionTo('loaded.created.uncommitted')
This will move a model into the sate of an old model that has been updated, think old dirty model:
record.get('stateManager').transitionTo('loaded.updated')
As of ember-data 1.0.0-beta.12:
record.transitionTo('loaded.saved');
It seems that record.get('stateManager') is not required anymore.
Here's what seems to work for Ember Data 1.0.0-beta.10:
record.set('currentState.stateName', 'root.loaded.saved');
record.adapterWillCommit();
record.adapterDidCommit();
record.set('currentState.isDirty', false);
Not sure if all those lines are required but just following what others have done prior to this.
Ember 2.9.1
record.set('currentState.isDirty', false);
Tested on Ember Data 2.9
pushedData action is the way to go but besides that the "originalValues" need to be reset as well.
Ember.assign(record.data, record._internalModel._attributes);
Ember.assign(record._internalModel._data, record._internalModel._attributes);
record.send('pushedData');
It looks like with newer versions everything methioned here got broken.
This worked for me with ember-data 1.0.0.beta4:
record.adapterWillCommit();
record.adapterDidCommit();
Another method that worked for me when using Ember Data 1.0.0-beta.18:
record.rollback()
This reversed the dirty attributes and returned the record to a clean state.
Seems like this may have been since deprecated in favor of record.rollbackAttributes: http://emberjs.com/api/data/classes/DS.Model.html#method_rollbackAttributes
I work on Ember data 1.13 so I used the following solution (which seems a mix between the one provided by #Martin Malinda and the other by #Serge):
// Ensure you have the changes inside the record
Object.assign(record.data, record._internalModel._attributes);
Object.assign(record._internalModel._data,record._internalModel._attributes);
// Using the DS.State you can first simulate the record is going to be saved
record.get('_internalModel').send('willCommit');
// Cleaning the prevous dirty attributes
record.get('_internalModel')._attributes = {};
// Mark the record as saved (root.loaded.created.uncommitted) even if it isn't for real
record.get('_internalModel').send('didCommit');
In this way, if we will call a further rollbackAttributes() on this record, if we will have some dirty attributes, the record will be reset to this last state (instead of having the original properties) which was exactly what I was looking for in my use case.
If we won't have any dirty attributes, nothing will change and we will keep the last attributes set using this code without having them rolled back to the original ones. Hope it helps.
Tested on Ember Data 3.8.0
Just an update to Martin Malinda's answer:
// Clear changed attributes list
record._internalModel._recordData._attributes = {};
// Trigger transition to 'loaded.saved' state
record.send('pushedData');
In my case I also needed to override serializer's normalize method.

read objects persisted but not yet flushed with doctrine

I'm new to symfony2 and doctrine.
here is the problem as I see it.
i cannot use :
$repository = $this->getDoctrine()->getRepository('entity');
$my_object = $repository->findOneBy($index);
on an object that is persisted, BUT NOT FLUSHED YET !!
i think getRepository read from DB, so it will not find a not-flushed object.
my question: how to read those objects that are persisted (i think they are somewhere in a "doctrine session") to re-use them before i do flush my entire batch ?
every profile has 256 physical plumes.
every profile has 1 plumeOptions record assigned to it.
In plumeOptions, I have a cartridgeplume which is a FK for PhysicalPlume.
every plume is identified by ID (auto-generated) and an INDEX (user-generated).
rule: I say profile 1 has physical_plume_index number 3 (=index) connected to it.
now, I want to copy a profile with all its related data to another profile.
new profile is created. New 256 plumes are created and copied from older profile.
i want to link the new profile to the new plume index 3.
check here: http://pastebin.com/WFa8vkt1
I think you might want to have a look at this function:
$entityManager->getUnitOfWork()->getScheduledEntityInsertions()
Gives you back a list of entity objects which are persisting yet.
Hmm, I didn't really read your question well, with the above you will retrieve a full list (as an array) but you cannot query it like with getRepository. I will try found something for u..
I think you might look at the problem from the wrong angle. Doctrine is your persistance layer and database access layer. It is the responsibility of your domain model to provide access to objects once they are in memory. So the problem boils down to how do you get a reference to an object without the persistance layer?
Where do you create the object you need to get hold of later? Can the method/service that create the object return a reference to the controller so it can propagate it to the other place you need it? Can you dispatch an event that you listen to elsewhere in your application to get hold of the object?
In my opinion, Doctrine should be used at the startup of the application (as early as possible), to initialize the domain model, and at the shutdown of the application, to persist any changes to the domain model during the request. To use a repository to get hold of objects in the middle of a request is, in my opinion, probably a code smell and you should look at how the application flow can be refactored to remove that need.
Your is a business logic problem effectively.
Querying down the Database a findby Query on Object that are not flushed yet, means heaving much more the DB layer querying object that you have already in your function scope.
Also Keep in mind a findOneBy will retrieve also other object previously saved with same features.
If you need to find only among those new created objects, you should make f.e. them in a Session Array Variable, and iterate them with the foreach.
If you need a mix of already saved items + some new items, you should threate the 2 parts separately, one with a foreach , other one with the repository query!

Repository Pattern

I've got a quick question regarding the use of repositories. But the best way to ask is to show a bit of pseudocode and you guys tell me what the result should be
Get a record from the repository with ID of 1 (assume it exists)
Edit a couple of properties
Query the repository again for an item with ID of 1
Result = ??
Should I get the object with updated values or the object without (original state), bearing in mind that since updating the values of properties (step 2) I have not told the repository to update this record.
I think I should get a copy of the original item and not a reference to the edited version.
Please tell me what is correct.
Cheers
The repository pattern is suppose to act like a collection of your objects, so ideally I think it should return the same object instance which would have the updates in it.
Generally there is an identity map somewhere so your repositories can keep track of what has already been loaded. With an identity map, when you fetch an object with the same Id you should always get the already loaded object back regardless of how many times. This is how all more sophisticated ORMs work and is generally a good practice. An identity map helps keep things in sync while you are in the same transaction and saves you some data access.
NHibernate's session has an identity map it keeps track of so you don't have to worry about trying to implement your own in your repositories. Also I believe you can use NHibernate's stateless session if you want to load another instance without change tracking, but I'm not positive on that.
Judging from your past questions I'm assuming you are using LINQ/C#?
If you are using a DataContext and you haven't called SubmitChanges() then you should get back the original unchanged object.
Just tested it. I was wrong, you get back the changed object.
If you set ObjectTrackingEnabled = false on the DataContext you will get the unchanged object.