I am using EclipseLink JPA implementation. I need to persist an entity with null primary key. The key are generated by a trigger and therefore must always be null for new rows. Nothing can be changed in the database, so none of the #GeneratedValue options is suitable.
I tried #PrimaryKey(validation=IdValidation.NONE), but it does not help.
I always receive an error like:
Exception Description: Null or zero primary key encountered in UnitOfWork clone
Currently I am using a simple insert statement.
Could anyone suggest what to change to be able to use persist() method with new entities with null pk?
Thanks
Related
I really have a weird issue now.
I just want to delete an entity.
I am also using Hibernate envers for auditing. So now I want to delete this entity.
Now I get following message.
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
Column 'succeed' cannot be null
So when I removed #Audit from my table all of a sudden I was able to delete the entity.
Now I went to my entity_aud table and deselected NOT NULL for attribute succeed. Then I also again put #Audit above my table.
Now it worked. So why if I want to just delete an entity, I get a NOT NULL error when using Hibernate Envers.
What is the reason for this.
When an entity is removed, Envers will also generate an audit entry for that operation. By default, entity data is not captured when a delete audit record is produced, so essentially Envers attempts to insert a row into the audit table that contains the Primary Key, Revision Number, and Revision Type. All the other columns will be inserted with null values.
Since your audit table had the succeed column specified as NOT NULL, the delete throw an exception.
Besides the primary key, revision, and revision type columns in the audit table, all other columns should be created without the NOT NULL specification for this reason, meaning they are allowed to be NULL. If you can reproduce Envers generating tables that do not adhere to this, please report it as a bug by attaching the entity model to the issue.
A configuration setting, org.hibernate.envers.store_data_at_delete when set to true will tell Envers to not only capture the entity's primary key, revision, and revision type, but all audited columns. This is not enabled by default because in general, the prior revision maintains that same state so replicating it is really unnecessary; however, some users prefer to have it.
Entity Framework 6 Casscading Deletes and DropForeignKey fails on auto generated constraint name
I've been running into a bit of an issue with Entity Framework and cascade deletes between two tables on several one-to-many relationships.
Initially it looked like the correct path to take was to configure the table mappings with the OnModelCreating method of DbContext turning off cascade delete in a manner such as
modelBuilder.Entity<SourceTable>()
.HasOptional(x => x.NavigationProperty)
.WithOptionalDependent()
.WillCascadeOnDelete(false);
This however did not work throwing an exception stating
Cannot delete or update a parent row: a foreign key constraint fails...
More research lead me to believe that this is because all affected entities must be loaded into the context (eager fetched) so that entity framework may set the FK references to null as part of the transaction. This is not practical for my needs based on the size of the relational graph I'd be dealing with.
My next approach was to modify the Seed method of the Configuration class and run some arbitrary SQL to drop the Foreign Key constraint and re-add it as a ON DELETE SET NULL constaint. This worked in most cases, however one of the consraints has what appears to be an auto generated unpredicatable name that is diffrent on each call of Update-Database. Given that the name can't be predicted the ALTER statments aren't particualr helpful
context.Database.ExecuteSqlCommand(#"ALTER TABLE SourceTable DROP FOREIGN KEY FK_9405957d032142c3a1227821a9ed1fdf;
ALTER TABLE SourceTable
ADD CONSTRAINT FK_ReasonableName
FOREIGN KEY (NavigationProperty_Id) REFERENCES NavigationProperty (Id) ON DELETE SET NULL;");
Finally, I've taken the apprach to use the migration functionality (DbMigration) and override Up method and leveraging the DropForeignKey method along side more explicit SQL to re-add the constraint (EF does not appear to provide a factility to create a ON DELETE SET NULL constraint).
DropForeignKey("SourceTable", "NavigationProperty_Id", "DestinationTable");
Sql("ALTER TABLE SourceTable ADD CONSTRAINT FK_ReasonableName FOREIGN KEY (NavigationProperty_Id) REFERENCES DestinationTable (Id) ON DELETE SET NULL;");
This works great, up until I encounter the constraint with the auto generate name. At this point the DropForeignKey method fails with an exception that is swallowed up by
System.Runtime.Serialization.SerializationException: Type is not resolved for member 'MySql.Data.MySqlClient.MySqlException,MySql.Data...
When dumping the migration to a SQL script file it becomes clear that the DropForeignKey simply generates a FK with a more predictable, non-ambiguous byte stream array.
Is there a proper EF Code First approach to solve the problem of setting FK column values to null when deleting the refrenced row, or am I stuck having to hand code SQL in order to gain this functionality?
I need to map some external database, I can't modify the schema. But the tables don't have primary key but rather columns like Client_ID, Calendar_ID but they are not null and entity can map them, much worse is if these columns in few tables can be null, then Entity Framework throws an error that it can't be mapped.
My question is: can I somehow disable entity tracking and map these tables without primary key and with columns as null?
Or can I use code-first approach, does it let me to create and map class with no primary key and all columns as is null?
Entity Framework must have a key field in order to work. It doesn't have to be a true primary key in the database but it needs to be unique. If you have tables that have a nullable field and no true primary key and you can't modify the database then maybe Entity Framework isn't the best fit for this project. It might work if you never try and load the entities with the null values, but it will throw errors when you do (as you have noticed).
I have simple OneToOne relationship:
Data <-> TherapyResult
I would like to express the following constraints
with JPA.
If a Data entity gets removed the associated TherapyResult should be delete,too
If a TherapyResult entity gets removed the associated Data entity should remain in the db
The first constraint is really easy with JPA as I can add CascadingType.REMOVE
#OneToOne(cascade = { CascadeType.REMOVE, CascadeType.REFRESH })
private TherapyResult therapyResult;
For the second constraint I would like to add something like
#JoinColumn(columnDefinition = "DATA_ID BIGINT CONSTRAINT THERAPYRESULTDTAID FOREIGN KEY (DATA_ID) REFERENCES DATA (ID) ON DELETE SET NULL")
However this does not work. OpenJPA seems to have something similiar, but I want to use JPA 2.0 and EclipseLink. OpenJPA ForeignKey.
Another solution would be using #PreRemove described here, which works but looks a bit "none-best-practices" to me. However just a feeling.
My setup is:
Eclipse 3.7.1
EclipseLink 2.3
Apache Derby 10.8.3 and/or HSQLDB
any help is appreciated,
Muki
You can't use pure JPA to specify foreign keys ... that spec doesn't include the ability. JDO is the only standard with the ability to define FKs. You have to use implementation specifics, or just define the schema yourself and let the JPA impl run on it.
If you have a foreign key from Data to TherapyResult, and Data is the owner of the association, then
removing the Data will delete the TherapyResult automatically if cascade is set to REMOVE
you just need to set the therapyResult field to null and then delete the TherapyResult to have what you need. Another option is to set orphanRemoval to true, in which case setting the therapyResult field to null is sufficient to remove it from the database
If you have a foreign key from TherapyResult to Data, and TherapyResult is the owner of the association, then
removing the Data will delete the TherapyResult automatically if cascade is set to REMOVE on the Data.therapyResult field.
removing the TherapyResult will leave the Data in the DB provided the cascade is not set to REMOVE on the TherapyResult.data field
I have a table called farmers. Each farmer has a country specified that is mandatory.
When I add a new farmer to the database using antity framework, I get a violation on the country table. It looks like the entity framework wants to add the country to the country table, but I only want the guid in my farmer table:
Violation of PRIMARY KEY constraint 'PK_Country'. Cannot insert
duplicate key in object 'dbo.Country'. The statement has been
terminated.
Can somebody advise me on what I'm doing wrong? here the code for the insert:
newFarmer.Guid = Guid.NewGuid();
ents.Farmer.AddObject(newFarmer);
ents.SaveChanges();
return newFarmer;
I even checked the state of the country and it says unchanged.
One possible solution is that Entity Framework doesn't understand that your entity primary key is also the identity and should be auto-incremented. I had the same problem in an application using EF 4.1 with database first. To solve the problem, I had to::
Make sure my entities primary key had a name "ID" (to avoid putting a decorator [Key] above my Model class.
Make sure the property option "Identity" of your database system (SQL Server in my case) is set to "Yes".
Then, my EF4.1 was able to do the insert and update of my entities.
Hope this helps!