I have a Spring application where the Domain Object identifier is not assigned by the database, but it generated by the application. The identifier is generated and added to the Domain Object during the BeforeSave callback. After saving the domain object (Insert), when trying to save the domain object with the same identifier (Update), I receive the following error
Caused by: org.springframework.dao.IncorrectUpdateSemanticsDataAccessException: Failed to update entity [com.example.UUIDTest.DomainObjectLongId#77ccded4]. Id [2997744842191684912] not found in database.
I have created several test examples. In the DomainObject example, I am generating the ID as a UUID. In the DomainObjectLongId example, I am generating the ID as a Long. In both of these examples, it fails on the save (Update) when using the Spring-Data-JDBC repository. Manually generating SQL and using it to update works successfully.
I have created a test example that has the DB autogenerating the ID. In this situation upon saving (Update), it succeeds without any errors.
How do I get Spring-Data-JDBC to update a domain object using a provided id?
Below is the Github repository with all 3 test classes. Two of which fail on save (Update) with provided identifier and one of which succeeds on save (Update) with auto generated identifier.
Github Spring-Data-JDBC-UUID-Test
Finally figured it out. I was always changing the ID of the DomainObject
aggregate.setId(UUID.randomUUID());
return aggregate;
I needed to check to see if it needed to be set
if (aggregate.getId() == null) {
aggregate.setId(UUID.randomUUID());
}
return aggregate;
Related
I am trying to host a metadata file and act as an IdP.
To generate the metadata I used the following online tool https://www.samltool.com/idp_metadata.php
After filling out the form and building it, the validUntil attribute is set to be the current timestamp.
When trying to test this metadata with https://samltest.id/upload.php it says expired.
When I increment the year and try again the metadata date doesn't seem to change.
How can create an IdP metadata file that is valid?
You can manually change the validUntil value according with your requirement. There won't be any issue during validation on the aforementioned site.
To verify, I just quickly ran through changing the field value and my input meta-data passed the validation.
original
and updated
results.
I am retrieving data over an API and displaying it in my web application as shown:
The obvious problem being that I need Last Edited By to show the users name, rather than their GUID.
I use Identity Server 4, so UserProfile details are all held in a separate (OAuth) database.
The flow for returning data to the web app is as follows, and I'd like to know how I could return First and Last name from the OAuth database, instead of user IDs (guids)
My query in the repository at the moment is simply:
public IEnumerable<Survey> GetSurveys()
{
var surveys = _context.Surveys
.Include(s => s.SurveyStatus)
.ToList();
return surveys;
}
The issue is that you are missing the information in your (business) database. First and last name are actually both identity information as business information. This means that first and last name should be part of both the identity model and business model.
To solve this: add a user table (containing userId, first and last name) and update the table with information when a user logs in.
Since you are logging activity of a logged in user, you always have the information you need. So there is no need to query the user table in the Identity Model. For a first setup you may want to create the new table using information from the identity database.
Though information is stored multiple times, it is not redundant. In fact, you would do the same thing when storing information about external logins.
Most of the time when you have an external identity provider, you'll keep certain claims on authenticated users as part of a local profile.
For logging / auditing, you would use their identity key from the external identity provider as well a foreign key to the user's record in your profile table. I would keep this so that you have access to the correct record in profiles even when they are not logged in (and the record will remain updated for as long as the user continues coming back).
When a user logs in, you can check their claims against your profiles table and update it. Then when you look at the audit info or logs, the db query would be getting the updated profile information.
We have three Organization tenents, Dev, Test and Live. All hosted on premise (CRM 2011. [5.0.9690.4376] [DB 5.0.9690.4376]).
Because the way dialogs uses GUIDs to refference record in Lookup, we aim to maintain GUIDs for static records same across all three tenents.
While all other entities are working fine, I am failing to import USERS and also maintain their GUIDS. I am using Export/Import to get the data from Master tenent (Dev) in to the Test and Live tenents. It is very similar to what 'configuration migration tool' does in CRM 2013.
Issue I am facing is that in all other entities I can see the Guid field and hence I map it during the import wizard but no such field shows up in SystemUser entity while running import wizards. For example, with Account, I will export a Account, amend CSV file and import it in the target tenant. When I do this, I map AccountId (from target) to the Account of source and as a result this account's AccountId will be same both in source and target.
At this point, I am about to give up trying but that will cause all dialogs that uses User lookup will fail.
Thank you for your help,
Try following steps. I would strongly recommend to try this on a old out of use tenant before trying it on live system. I am not sure if this is supported by MS but it works for me. (Another thing, you will have to manually assign BU and Roles following import)
Create advance find. Include all required fields for the SystemUser record. Add criteria that selects list of users you would like to move across.
Export
Save file as CSV (this will show the first few hidden columns in excel)
Rename the Primary Key field (in this case User) and remove all other fields with Do Not Modify.
Import file and map this User column (with GUID) to the User from CRM
Import file and check GUIDs in both tenants.
Good luck.
My only suggestion is that you could try to write a small console application that connects to both your source and destination organisations.
Using that you can duplicate the user records from the source to the destination preserving the IDs in the process
I can't say 100% it'll work but I can't immediately think of a reason why it wouldn't. This is assuming all of the users you're copying over don't already existing in your target environments
I prefer to resolve these issues by creating custom workflow activities. For example; you could create a custom workflow activity that returns a user record by an input domain name as a string.
This means your dialogs contain only shared configuration values, e.g. mydomain\james.wood which are used to dynamically find the record you need. Your dialog is then linked to a specific record, but without having the encode the source guid.
In crm 2011, inside the Execute method of a plugin, how can I know the id of the registered step that is executing? For instance, I have two steps for the pre create of an account. The execute method will run two times one for each step. I need to know in the execute method the stepid of the step that is actually running. I can't find it in the context.
UPDATE:
I'm updating here to explain the scenario, because in the comments I don't have enough characters. So the scenario:
I have a solution for autonumbering entities that enables users to format their numbers the way they want.
For that I have an entity (autonumber) where they configure the format, the entity and the field they want to number. Every time a record is created for the autonumber entity it will create and register a step dynamically in the pre operation of the create message of the entity to be numbered, for example the account.
When that step is executed it will load the autonumber record to know how to number the account field.
The created step must be linked to the autonumber record and for that the autonumber entity has an attribute to store the id of the step. This attribute is filled on the pre create of the autonumber entity when the step is created.
This link attribute allows for the step to be unregistered when the user deletes the autonumber record because it knows exactly which step to unregister. It also allows the user to set the order in which the step is going to be executed if there are more plugins registered to the account.
The problem that I had was when I wanted to number 2 or more attributes for the same entity. In this case the users would create, lets say, 2 records of the autonumber entity in order to number 2 fields of the account. In this case I will have 2 steps registered to the account. When the account is being created one step will number one field and the other step will number the other field. That's why I need to know the id of the step that is being executed in order to load the right autonumber record.
Sorry for the tedious explanation but this scenario is a bit complex and I'm not sure if I was clear enough, but if you want I'll try to be more clear.
The OwningExtension property available on the IPluginExecutionContext will return an EntityReference to the SdkMessageProcessingingStep which should provide all the information you need.
What are you trying to achieve by registering the same plugin twice for the same Message and Stage? I'm struggling to think of a valid scenario.
You can get the name of the message from the context. Usually, I do something similar to this.
public void Execute(IServiceProvider serviceProvider)
{
IPlugingExecutionContext context
= (IPlugingExecutionContext)serviceProvider
.getService(typeof(IPlugingExecutionContext));
switch(context.MessageName)
{
case "Create" ExecuteCreate(); break;
case "Retrieve" ExecuteCreate(); break;
case "Update" ExecuteCreate(); break;
case "Delete" ExecuteCreate(); break;
default ExecuteFunctionality(Context.MessageName);
}
}
Then, of course, you need to implement those methods too. And usually I have a private field that hold the reference to context. It's good to be able to access it easily when the need arises. Also, you can (and should) check if the message is supported by your plug in, if there's a Target and if it's of the right entity type. Stuff like that.
0x80040237 Cannot insert duplicate key.
I'm trying to write an import routine for MSCRM4.0 through the CrmService.
This has been successful up until this point. Initially I was just letting CRM generate the primary keys of the records. But my client wanted the ability to set the key of a our custom entity to predefined values. Potentially this enables us to know what data was created by our installer, and what data was created post-install.
I tested to ensure that the Guids can be set when calling the CrmService.Update() method and the results indicated that records were created with our desired values. I ran my import and everything seemed successful. In modifying my validation code of the import files, I deleted the data (through the crm browser interface) and tried to re-import. Unfortunately now it throws and a duplicate key error.
Why is this error being thrown? Does the Crm interface delete the record, or does it still exist but hidden from user's eyes? Is there a way to ensure that a deleted record is permanently deleted and the Guid becomes free? In a live environment, these Guids would never have existed, but during my development I need these imports to be successful.
By the way, considering I'm having this issue, does this imply that statically setting Guids is not a recommended practice?
As far I can tell entities are soft-deleted so it would not be possible to reuse that Guid unless you (or the deletion service) deleted the entity out of the database.
For example in the LeadBase table you will find a field called DeletionStateCode, a value of 0 implies the record has not been deleted.
A value of 2 marks the record for deletion. There's a deletion service that runs every 2(?) hours to physically delete those records from the table.
I think Zahir is right, try running the deletion service and try again. There's some info here: http://blogs.msdn.com/crm/archive/2006/10/24/purging-old-instances-of-workflow-in-microsoft-crm.aspx
Zahir is correct.
After you import and delete the records, you can kick off the deletion service at a time you choose with this tool. That will make it easier to test imports and reimports.