Hibernate #Id and oracle Unique constraint - oracle

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 ...

Related

how to add columns to database table that are not contained in Entity

If I want to have DB table with scheme
id|column1|rest of columns...
such as:
#Entity
#Table(name = "SampleEntity")
class SampleEntity(
#Id #GeneratedValue val id: Long,
)
how can I add columns to table such that the table has these columns, but my entity does not?
I would like to be able to add these columns programmatically with a for loop. But any pointers would be appreciated.
If you want to alter table programatically just use spring-jdbc (https://www.baeldung.com/spring-jdbc-jdbctemplate) which will allow you to execute SQL queries thus make changes to table programmatically.
It is completely ok if your entity doesn't have all the columns - columns that don't have matching attributes inside of the class just will be ignored by the entity in Spring JPA. Alternatively, you could just use spring-jdbc with a custom row-mapper.

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).

Strange self-referencing constraint violation after upgrading Hibernate

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.)

Doctrine - Table without primary keys

I use doctrine.
It's possible to generate entities who based on a database with table (important) without primary key ?
The DB is for Chacal XXI (an application) and 1 or 2 tables have not primary keys, i can't add primary key manually.
No. From https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/basic-mapping.html#identifiers-primary-keys :
Every entity class must have an identifier/primary key. You can select the field that serves as the identifier with the #Id annotation.

Linq2Sql: Can I create entities with foreign key relationships without a primary key in both tables?

I have 2 tables in my database that I'm trying to create Linq2Sql entities for. There's more to them than this, but this is essentially what they come down to:
Rooms UserActivity
-------- --------
RoomID ActivityID
RoomID (foreign key on Rooms.RoomID)
The UserActivity table is essentially just a log for actions a user performs against the Rooms table.
Since the UserActivity table is only used for logging actions taken, it didn't make a lot of sense (to me at least) to create a primary key for the table originally, until the Linq2Sql mapper refused to make UserActivity a part of the Room entity in my Linq entities. When I set up the entities in the Visual Studio designer, I got these 2 warnings:
Warning 1 DBML1062: The Type attribute 'UserActivity' of the Association element 'Room_UserActivity' of the Type element 'Room' does not have a primary key. No code will be generated for the association.
Warning 2 DBML1011: The Type element 'UserActivity' contains the Association element 'Room_UserActivity' but does not have a primary key. No code will be generated for the association.
These warnings led me to create the ActivityID column in my table as displayed above.
What I'd like to know is if there is any way to allow Linq2Sql to create relationships between my entities without having a primary key in both tables. If I don't have the primary key in the UserActivity table, the entities can still be created, but the relationships aren't generated.
Is is it possible to do this, or should I try to make sure my tables always have a primary key in them as a general good practice?
Any table that stores real data in your app should always have a primary key - most cases, in SQL Server environments, a INT IDENTITY(1,1) will be just fine. You don't have to keep track of those, no bookkeeping necessary etc. It doesn't cost you much, totally easy to do - I don't see any reason why not have a primary key, even on your UserActivity table.
ALTER TABLE UserActivity
ADD UserActivityID INT IDENTITY(1,1)
CONSTRAINT PK_UserActivity PRIMARY KEY
and you're done!
The only time I would say no primary key is needed is for things like temporary tables when bulk importing huge amounts of data, or other temporary scenarios.
Marc
You need a primary key to create relationships.
It's good practise to always design tables with primary keys, even if you add surrogate (auto increment identity).

Resources