Deleting and renaming attributes in Attribute Dictionary in Websphere Commerce - java

I have two attributes in my attribute dictionary. One is SAMPLE_ATTRIBUTE and the other one is MODEL_ATTRIBUTE. If I delete SAMPLE_ATTRIBUTE, and want to rename MODEL_ATTRIBUTE to SAMPLE_ATTRIBUTE, can I do it? Will the change reflect right away? Or is there anything that need to be “run” to purge that reference before I can rename another attribute with the same name?

you can delete the dictionary attribute as long as it is not referenced by other products, if it is referenced (assigned to other products), you can not delete manually from CMC before you go and delete the attribute from referencing product.
you can rename dictionary attribute to another one as long as the identifier is unique, and it will save your changes instantly yo database
if you use this dictionary as facetable attribute, what I encountered in previous project that deleting the dictionary attribute will leave the record in SRCHATTR table, so I have to delete the record manually using SQL before i can mark it facetable again.
front-end store (Aurora) is using Apache solr for product browsing, product detail & search, deleting or changing in facetable dictionary attribute will trigger Full Solr indexing to your products, you need to make sure that you have the schedule job "UpdateSearchIndex" scheduled at site level , otherwise solr indexing will not occur and hence you will not see your changes reflected.
in FEP7+, triggering UpdateSearchIndex" job will also invalidate dynacache records for that product . not sure about FEP6 but this feature is not there before FEP6 , so if you have Caching enabled, you need to figure out way to invalidate those product caches (normally by writing sql triggers)
hope that answers your question and give you what you need.
Thanks
Abed

Related

Add Column to Cassandra db with out losing data

I am using Cassandra database integrated into a spring boot application.
My Question is around the schema actions. If I need to make structural changes to the DB, say add a column to a table, the database needs to be recreated, however this means all the existing data gets deleted:
schema-action: CREATE_IF_NOT_EXISTS
The only way I have managed to solve this is by using the RECREATE scheme action, but as mentioned earlier, this results in data-loss.
What would be the best approach to handle this? To add structural changes such as a column name with out having to recreate the database and lose all existing data?
Thanks
Cassandra does allow you to modify the schema of an existing table without recreating it from scratch, using the ALTER TABLE statement via cqlsh. However, as explained in that link, there are some important limitations on the kind of changes you can do. You cannot modify the primary key of the table at all, you can add or delete regular columns, and you can't change the type of a column to a non-compatible one.
The reason for most of these limitations is how Cassandra needs to deal with the old data that already exists in the table. For example, it doesn't make sense to say that a column A that until now contained strings - will now contain integers - how are we supposed to handle all the old values in column A which weren't integers?
As Aaron rightly said in a comment, it is unlikely you'll want to do these schema changes as part of your application. These are usually rare operations which are done manually, or via some management application - not your usual application.

Looking for the right solution to store filenames

Just started out with my hobby project and now I am here to get help with making the correct database design/query. I have made a simple Java program that loops trough the content of a folder. I want to save this content to a MySQL database, so I added a connector to my database in Java, created a table and the columns "file", "path" and "id, "date" in MySQL.
So now to the important/fun thing, every time I want to add the filenames to the MySQL in Java I do this (when the GUI-button is pressed I call on a method that does):
DELETE all entries with the same file path - this is to ensure that I will get new entries which is exactly the same as the content in the path.
Java-loop: INSERT the file-info into the columns id, path, filename and date when the file was added to the database.
In this way I can always ensure that the filenames that are going to be added into the database always are up to date, it doesn't matter if I rename a file or remve it, it will be up to date since the table will get it's entries deleted and new info will be written. Old info -> DELETE old info - INSERT new info -> Up-to-date.
I know this is probably not the best solution but it works, but now I am stuck on the next thing I want to do. I want to add the difference of the files in order to know which files has been added and deleted between two inserts, and here is my problem, since the entries are deleted before a new INSERT I cannot compare. How would you change the design or the solution? All ideas are welcome and since I am so fresh I would really appreciate if you could show me how the query could look like.
Do not remove all rows first. Remove only the ones that are removed (or event better, just mark them "inactive" as I suggest below). Query your DB first, to see what was there last time.
I would maintain additional column in your table called "inactive". It will be FALSE as default, and TRUE for removed files. Please keep in mind that as your file is uniquely identified by file+path+id renaming any file is indeed an operation of deleting the old one and creating the new one.
Removing things from DB is not a good idea, as you might always remove something by accident (bug in the code) and would not be able to get the data back.
Additional thing to do is adding the hash to your table. This way you will be able to check if the file was really changed. There is no need to re-add the file to the DB is it is not changed. See Getting a File's MD5 Checksum in Java for more info.
One way to achieve this is to implement auditing of your table. A common approach is to create a copy of the table where you are storing the folder contents and name that table using a convention to indicate it is storing audit information (eg. _AUD) . You then add additional columns to the AUD table, like "REV" (revision), "REV_TYPE" (inserted, deleted, modified). Whenever you insert, update or delete any rows from your main table, you insert a row into the AUD table to describe what you've done. Then you can find the operations associated with each revision by looking it up in the AUD table. A java framework that provides this feature is hibernate envers (http://hibernate.org/orm/envers/).

Possible overwriting to database table

Let's say you have a database table name table1 with columns name and surname. Two different clients open the same view from the java application and get the data for same person at the same time.
1) First client changed the name and pressed save button to update database record.
2) Client2 still sees the old record on the screen and then pressed to save button to change the surname.
It actually overwrite the record by old name. I think to check and get the latest data before updating the database when I click button but I do not like this solution because of making a second query before update.
So how can we solve this problem by using Hibernate and without using Hibarnete. Any idea?
Of course if you do not want that something will be overridden, then you have to check the data before an update. But it will be not always a real query with a good caching strategy. You could also use a timestamp with last update to compare it easier. Another strategy would be to lock the entities when the first user will read them. But that is normally not a good design for web applications or you have to integrate a messaging service, which will all user inform for an update who actually have open that entity. But I think that is not so easy to implement and a more advanced feature.
In short, compare the timestamp of an entity and if already updated, then compare the changes and show them for the user who wanted update that entity.

How to create an undo function in spring MVC based web app.?

I have an employee and a corresponding employee history table.
Both the tables have same structure. History table is used to track the historical changes made to the employee over a period of time.
Now, I need to add an undo function to the changes made to the employee.
e.g. Employees title is changed on 1st August. Now, This will update the employees title in Employee table and insert an corresponding history record in employee_history table.
Now, I need to undo this change. Employee edit page will have a list of changes made to employee datewise with an undo button beside it.
Clicking on undo should revert changes in Employee table to previous value. Also I think the record in history table which says title is changed, should also be removed.
Also when I revert tghe changes to employee table i.e. revert title to previous title, this will fire an insert to history table, which I dont want.
I am not sure what is the best possible way to do this.
Any suggestions will be helpful.
In case you want to implement a "persistent" undo - one that would survive an application restart/session timeout, you should consider extending your DB schema width timestamp fields and either delete the last entry or replace it with an appropriate earlier entry.
A "light" version would be using a stack to store last interactions, including the original and the new value. You could persist the stack on session invalidation of course to combine both approaches. This seems to be what you are actually doing.
You could extend this solution by creating and storing or exporting SQL migration scripts for each change, recording the change and, if possible, the opposite action. So you could even transfer the scripts between application instances and environments and would have a complete "replayability" of your DB states.
tl;dr - it looks like you have already implemented a good solution
I would suggest using a flag telling the trigger/history logic to keep off while you have your undo running and not writing history data.
Normally this would be done by serializer-class feeding from your history table and restoring employee data and later cleaning up history-entries/unlocking history again.
You could maybe use the rollback feature of the transaction.

Solr. Updating a document multi-value field (no dup values) without needed it to be already committed

Sorry for the lengthy text, it's a bit difficult to explain:
We are using Solr to index some user info like username, email (among other things).
I'm also trying to use facets for search, so for example, I added a multi-value field to user called "organizations" where I would store the name of the organizations that user work for.
So i can use that field for facetted search and be able to filter a user search query result by the organizations this user work for.
So now, the issue I have is my code does something like:
1) Add users documents to Solr
2) When a user is assigned an organization membership(role), update the user doc to set the organizations field
Now I have the following issue with step 2:
If I just do a addField("organizations", "BigCorp") on the user doc, it will add that value regardless if organizations already have that value("BigCorp") or not, but I want each org name to appear only once.
So only way I found to get that behavior is to query the user document, get the values of "organization" and only add the new value if it's not already in there - if !userDoc.getValues("organiations").contains(value) {... add the value to the doc and save it ...}-
Now that works well, but only if I commit all the time(between step 1 & 2 at least), because the document query will not work unless it has been committed already. Obviously in theory its best not to commit all the time performance-wise, and unpractical since I process those inserts in batches.
So I guess the main issue would be:
Is there a way to update a multi-value field, without allowing duplicates, that would not require querying the doc to manually prevent duplicates ?
Maybe some better way to do this ?
Thanks.
Couple of things -
For multiple duplicate values in the faceted field, the value in faceted field is counted just once. So even if you add multiple same values, that would be reflected as a single value in the facet count entry. Have tested this. you too can confirm.
Also, when you reindex the document why would you need to check whats in the existing document. As I presume you would have the unique list of organizations and when fed to Solr, the document would be deleted and inserted.

Categories