Peristence using Open JPA ;Setting composite primary key to Id Attribute of Main entity - jpa

Server - IBM WAS 8.5
Open JPA 2.2.3
I am trying to perform a container managed persistence using entity manager.
I have the following three entities defined
Entity MainEntity
Has an id of the type MainEntityPK
MainEntityPK - has the SubEntity1Code from SubEntity1 table and SubEntity2Code from SubEntity2 Table.
Entity SubEntity1 - SubEntity1Code - primary Key
Entity SubEntity2 - SubEntity2Code - primary Key
I try to create an entity of MainEntity which has an existing SubEntity1 and SubEntity2 entries
I first find the entities of SubEntity1 and Seg using
SubEntity1 SubEntity1 =
Entitymanager.find(SubEntity1.class,SubEntity1Code)
SubEntity2 subEntity2 =
Entitymanager.find(SubEntity2.class,SubEntity2Code)
The fetch are successful and I have both the instances of subEntity1 and subEntity2
Now I try to set the Primary Key MainEntityPK as follows
MainEntityPK MainEntityPK = new
MainEntityPK(SubEntity1Code,SubEntity2Code);
MainEntity MainEntity = new MainEntity();
MainEntity.setId(MainEntityPK);
I am getting following error :
Caused by: <openjpa-2.2.3-SNAPSHOT-r422266:1802534 nonfatal user error> org.apache.openjpa.persistence.ArgumentException
: Field: “model.MainEntity.id” of “model.MainEntity#e8df5623” can not be set to “model.MainEntityPK#1768a2” value.
I tried removing the setId call and was getting error as follows:
Caused by: <openjpa-2.2.3-SNAPSHOT-r422266:1802534 nonfatal user error> org.apache.openjpa.persistence.ArgumentException
: Field: “model.MainEntity.id” od “model.MainEntity#e8df5623” can not be set to null value.
Can some one help me in identifying what is wrong in setting the instance of MainEntityPK to id attribute of MainEntity

Related

Adding data to Postgres database with Entity Framework Core HttpPost failing because of child table constraint

I am trying to add some data to a Postgres database using Entity Framework Core via a Http POST method.
The data to be added is passed in the body of my post request which looks like this:
{"id":42,"name":"Hans Musterman","email":"hans#gpost.com", "gender": {"id": 2, "name": "male"}}
Which is exactly the structure I would get returned using a get request.
Still the insert fails with an error:
Duplicate key value violates unique constraint "PK_Genders"
Of course the gender male already exists in the Genders table. What I want to do is add a user to the users table with a gender but referenced for the new user but not new created. What the system seems to do when using DbContext Add is trying to add User and Gender.
Is there a way to do it with a reference? Adding a User with "gender" = null does work.
I think you should have something like genderId or foreign key that reference the gender table in the user model use that foreign key id (genderId) instead of gender.
eg. in you user object
{ ... "genderId": 2 }
Otherwise Entity Framework is going to create a new gender that is why you are getting that error

more than one entity of type 'Model' have the same primary key value

I try to insert "Person" to Database after initialization but I get this problem:
An exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll but was not handled in user code
Additional information: Saving or accepting changes failed because more than one entity of type 'MyProject.Entities.Models.Person' have the same primary key value. Ensure that explicitly set primary key values are unique. Ensure that database-generated primary keys are configured correctly in the database and in the Entity Framework model. Use the Entity Designer for Database First/Model First configuration. Use the 'HasDatabaseGeneratedOption" fluent API or 'DatabaseGeneratedAttribute' for Code First configuration.
in this line :
private void SyncObjectsStatePreCommit()
{
foreach (var dbEntityEntry in ChangeTracker.Entries())
{
dbEntityEntry.State = StateHelper.ConvertState(((IObjectState)dbEntityEntry.Entity).ObjectState);
}
}
How can I deal please with this problem
thanks

Entity Framework delete and modify using guid and EntityState

I'm using Entity Framework to handle data transactions and we have a user entity which had a primary key type integer named ID.
In our SQL Server the Identity specification was set to Yes, Is Identity also set to yes with an auto increment of 1.
To delete a user, I used this code:
ctx.Users.Attach(user);
ctx.Entry(user).State = EntityState.Deleted;
ctx.SaveChanges();
However, we have changed our user entity to have a Guid as a primary key:
public class User
{
DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public Guid ID { get; set; }
public string Username { get; set; }
}
In the database, it is set to data type uniqueidentifier with a "Default Value or Binding" set to (newsequentialid())
After changing this, the Entity Framework code to delete a user throws the following error:
Attaching an entity of type 'Administration.Model.User' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.
Why is it throwing this error? I suppose it has something to do with the way the primary key is generated, but how can I fix this?
Of course, I could use a linq query and use .Remove, but I want to keep the solution I had using an int value as primary key.

Entity Framework: removing entity when One-to-One PK association is specified

I have existing DB with the following structure:
I'm using EF fluent API to configure relationships between tables:
public GroupEntityConfiguration()
{
HasMany(x => x.Employees).WithRequired().HasForeignKey(x => x.GroupId).WillCascadeOnDelete(true);
}
public EmployeeEntityConfiguration()
{
HasOptional(x => x.InnerGroupMember).WithRequired();
}
With this configuration applied I can add new Employee, new InnerGroupMember or fetch data. The problem appears when I try to remove Employee. Then I get an exception:
The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
As far as I understand above exception is connected with GroupId foreign key. Trying to fix it I'm adding following line to EmployeeEntityConfiguration:
HasKey(x => new { x.Id, x.GroupId});
But after adding it I get another exception which I believe is connected with InnerGroupMember object:
Invalid column name 'Guest_Id'. Invalid column name 'Guest_GroupId'.
If I comment out InnerGroupMember navigation property and remove it's configuration, Employee can be removed.
Could you please give me a hint what I'm doing wrong and how to configure entities to be able to perform all needed operations? Thanks!
I have an existing Group entity and I want to remove Employee from the Employees Group collection:
var group = groupRepository.Find(groupId);
group.RemoveEmployee(employeeId);
_unitOfWork.Save();
RemoveEmployee function inside Group entity looks like this:
public void RemoveEmployee(int employeeId)
{
var employee = Employees.Single(n => n.Id == employeeId);
Employees.Remove(employee);
}
That's why I get an exeption:
The relationship could not be changed because one or more of the foreign-key properties is non-nullable....
After reading this post I wanted to fix it adding HasKey(x => new { x.Id, x.GroupId}); function inside EmployeeEntityConfiguration what leads to the second exception:
Invalid column name 'Guest_Id'. Invalid column name 'Guest_GroupId'.
Actually I made this step (I mean adding HasKey function) without changing DB structure. To make it work, inside Employees table I have to create composite key - combination of Id and GroupId which is also a foreign key. This modification forces changes inside InnerGroupMembers table. DB structure looks now as following:
Now I'm able to remove Employee in a way I showed at the beginning.
Anyway I'm not going for this solution. They are different ways to achieve what I want. Here are some links:
Removing entity from a Related Collection
Delete Dependent Entities When Removed From EF Collection
The relationship could not be changed because one or more of the
foreign-key properties is non-nullable
For one-to-one relationships cascading delete is not enabled by default, even not for required relationships (as it is the case for required one-to-many relationships, that is: The WillCascadeOnDelete(true) in your one-to-many mapping is redundant). You must define cascading delete for a one-to-one relationship always explicitly:
HasOptional(x => x.InnerGroupMember).WithRequired().WillCascadeOnDelete(true);
When you delete an Employee now, the database will delete the related InnerGroupMember as well and the exception should disappear.

Entity Framework Conditional Mapping

I have a legacy database that has a table called Address. Now two other tables can have address information assigned to it. To determine which table it came from, there is a SourceID field. If the SourceID is 1 then it is associated with the first table, if it is 2, it is address information for the second table.
This legacy database doesn't have any foreign key constraints defined on the database, and it cannot be added.
I am wondering if I use Entity Framework to create a model that will have this association. Where table 1 can have an entity that has a navigation to address information (with the condition that the SourceID =1) and same with the second table.
I have tried created a conditional mapping and have it set "When SourceID = 1" I also removed the mapping from the column mapping as the column can only be mapped once. When I try to compile, I get the following error:
Error 3004: Problem in mapping fragments starting at line 683: No mapping specified for properties Address.SourceID in Set Addresses. An Entity with Key (PK) will not round-trip when: Entity is type [Model.Address]
Thanks for your help!
Don't use conditional mapping. Map your address to the entity without SourceID property and create two derived entities from the address entity. Use SourceID as discriminator (TPH inheritance - it works same as conditional mapping but you have multiple entities with different discriminator value). Relate your first and second entity to correct address sub entity.