Strange self-referencing constraint violation after upgrading Hibernate - spring

I'm using hibernate-entitymanager in a Spring application. I'm in the process of upgrading my Hibernate version. Narrowed it down to the exact version: when I upgrade from 4.2.1.Final to 4.2.2.Final (or anything higher than that), I'm getting the following error when my unit tests starts up and try to create the database schema:
2014-03-02 18:02:51,559 ERROR [SchemaExport] [main] HHH000389: Unsuccessful: alter table Incident add constraint FK_d91dua6gkdp1jn826adqss3aq foreign key (uuid) references Incident
2014-03-02 18:02:51,559 ERROR [SchemaExport] [main] Constraint "FK_D91DUA6GKDP1JN826ADQSS3AQ" already exists; SQL statement:
alter table Incident
add constraint FK_d91dua6gkdp1jn826adqss3aq
foreign key (uuid)
references Incident [90045-170]
The error does not prevent the system from working just fine, but clearly I can't go to production with such a nasty error in my system and no explanation of it.
This looks a lot like the Incident table has a foreign key relationship to itself, which is absolutely not the case.
I'll try to copy the essence here of the Incident entity:
#Entity
#Audited
#EntityListeners(value = {IncidentIdentifierPrePersistListener.class })
#FilterDefs( ... )
#Filters( ... )
public class Incident extends SomeBaseClass {
#Id
private String uuid = UUID.randomUUID().toString();
#Column(nullable = false, unique = true)
private long identifier;
... a bunch more fields ...
}
Please let me know if I can provide anything else to help ya'all to shed a light on this. I've played around with it for hours, fruitless, and your help would be much appreciated.

Here is what happened:
Incident defined a #ManyToOne to an entity Project
Project incorrectly defined a #ManyToMany back to the entity Incident (should have been a #OneToMany)
As a result Hibernate generated the awkward following constraint:
CONSTRAINT fk909a8f241708a1e FOREIGN KEY (uuid)
REFERENCES incident (uuid) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
Incident inherits SomeBaseClass which has #Inheritance(strategy = InheritanceType.JOINED)
As a result Hibernate generated the following constraint:
CONSTRAINT fk909a8f2ddd08e84 FOREIGN KEY (uuid)
REFERENCES somebaseclass (uuid) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
As a result of HHH-8217 (Make generated constraint names short and non-random) in Hibernate 4.2.2 the above two constraint definitions suddenly got the same name (Hibernate did only consider the entity and the columns of the foreign key constraint, not the target entity of the foreign key; note how generateName only takes one Table as a parameter)
And there was the corresponding clash: Constraint ... already exists
Changing the #ManyToMany to #OneToMany fixes this entirely.
By the way, the offending field definition (the one with the #ManyToMany) also previously caused me problems with Hibernate Envers' #Audited, the reason of which I never understood, and that got resolved now as well. It's a good day. (Not sure if #Audited means much for a mapped field, but at least I can have #Audited on the class without needing to deal with this field.)

Related

Hibernate doesn't add auto_increment

I'm running into an issue when running my SpringBootTests.
The tests are using an H2 database, so they recreate the schema every time they run. For one of my entities, Hibernate doesn't add auto_increment to the id column.
I can't find any relevant differences between the failing entity (Payment) and others that work correctly (e.g. Invoice). They all have the following annotations on the id field:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
I set spring.jpa.show-sql=true, and this is what I see:
The Payment entity shows create table payment (id bigint not null,
The Invoice entity shows create table invoice (id bigint not null
auto_increment,
In fact, I tried copying the Payment class to Payment2, and Payment2 did not have the issue:
The Payment entity shows create table payment (id bigint not null,
The Payment2 entity shows create table invoice (id bigint not null
auto_increment,
Given this, I believe I should be looking for an overriding configuration that's not in the Payment class, but that somehow removes auto_increment from just that one class.
Does anyone know what could be causing this?
These are the versions of the libraries involved:
Spring Boot version 2.1.8
Hibernate 5.3.11
H2 Database 1.4.200
I finally figured it out. This assumption was correct:
I should be looking for an overriding configuration that's not in the Payment class, but that somehow removes auto_increment from just that one class.
Turned out that a colleague had added a "light" read-only version of the Payment entity called PaymentLight. It read from the same payment table but without any of the joins. The id field in the PaymentLight class did not have the #GeneratedValue annotation.
I haven't checked this, but I assume Hibernate merged the two entities (the light class was a subset anyway) and used the #GeneratedValue configuration from one of them (likely alphabetical order).

#UniqueConstraint requires alter table in MariaDB if table already existed before with no constraints?

I apologize if I repeat the question, but I did not find a similar one.
I have added a unique constraint on an already existent table. We use MariaDB.
I have used the annotation:
#Table(uniqueConstraints={#UniqueConstraint(name="autonomy_name_energyType", columnNames={"autonomy","name","energyType"})})
The unit tests pass, but in the DB I am still allowed to create duplicates.
Do I need an ALTER table too? By checking the table I can see there are no constraints added to it.
Thanks
As explained in these SO posts :
Unique constraint not created in JPA
#Column(unique=true) does not seem to work
An explicit alter table query is needed for ur constaints to take effect on the db level.
As an extra info, it would have worked if the table was being re-created via JPA. see :
Add a unique constraint over muliple reference columns

Hibernate #Id and oracle Unique constraint

Can I use an hibernate entity with #Id on a unique constraint instead of a primary key on oracle databases? Also will it be JPA compliant?
Sounds a bit strange, but seems possible:
http://www.objectdb.com/api/java/jpa/Id:
The field or property to which the Id annotation is applied should be one of the following types: any Java primitive type; any primitive wrapper type; String; java.util.Date; java.sql.Date; java.math.BigDecimal; java.math.BigInteger.
But be aware:
(1) E.g. in Oracle UNIQUE does not imply NOT NULL, you have to ensure this by your own.
(2) You can't use a FOREIGN KEY constraint in your DB.
(3) You have to be careful with Id generation (http://www.objectdb.com/api/java/jpa/GeneratedValue) if you want to insert new entities (not only read existing ones).
(4) If you insert a new entity, you have to generate a value for the DB id.
And that are only a few disadvantages that came quickly to my mind ...

Webmatrix starter site userprofile fkey with othet table

I want to add to the UserProfile table of the StarterSite database created by the WebMatrix Starter Site template another column named email_pk (varchar 50) as primary key and add to id a foreign key constraint that references the Email column (varchar 50) of a new tb_contacts table. The latter column isn't a primary key.
When I try to do that manually in the WebMatrix Database workspace I get the following error:
There are no primary or candidate keys in the referenced table 'dbo.UserProfile' that match the referencing column list in the foreign key 'FK_tb_admin_user_UserProfile'.
Could not create constraint. See previous errors.
System.Data.SqlClient.SqlException (0x80131904): There are no primary or candidate keys in the referenced table 'dbo.UserProfile' that match the referencing column list in the foreign key 'FK_tb_admin_user_UserProfile'.
Could not create constraint. See previous errors.
at Microsoft.WebMatrix.DatabaseManager.SqlDatabase.SqlDatabaseProvider.EditTable(String connectionString, String schema, TableInfo tableInfo)
at Microsoft.WebMatrix.DatabaseManager.IisDbManagerModuleService.EditTable(DatabaseConnection databaseConnection, String schema, Object tableInfoData, String configPathState)
at Microsoft.WebMatrix.DatabaseManager.Client.ClientConnection.EditTable(String schema, Object tableInfoData)
at Microsoft.WebMatrix.DatabaseManager.Client.ClientTable.CommitChanges()
at Microsoft.WebMatrix.DatabaseManager.Client.TableDesignerViewModel.PerformSave()
ClientConnectionId:1da00f40-8f46-4c5b-b423-905c6990fd0d
If you want to add a foreign key to your UserProfile table, the referenced column must be a primary key or have a unique constraint.
You could manually add a unique constraint with a query like this:
ALTER TABLE tb_contacts
ADD UNIQUE (Email)
By the way, the New Relationship dialog of the WebMatrix Databases workspace displays as possible references only the tables with suitable primary keys.
Note that your StarterSite db alterations inhibit the use of the WebSecurity class.

Magento Model with Foreign Key Constraint

I am trying to create a model in my module that saves data and links against the customer_entity table. I have got the module saving the model without the foreign key constraint but as soon as I alter the table to include the constraint I get an integrity constraint violation exception even though I am including a customer id that exists in the customer_entity table.
Is there something extra I need to do with my model class or model resource class to get the model saving correctly?
There's too many things that could be a mitigating factor here. At some point Magento is running some set of SQL queries that temporarily (or possibly permanently) cause a foreign key constraint. The only way to solve this is to drop down below the Model layer and look at the actual SQL being run against your database.

Resources