Why do I get "Referential integrity constraint violation" with jpaDerivedIdentifier - jhipster

After using Jhipster to generate app from jdl file, I got error below at app startup. I only got this issue when I used jpaDerivedIdentifier on the OneToOne relationship to user table.
liquibase.exception.MigrationFailedException: Migration failed for change set config/liquibase/changelog/20201128181606_added_entity_constraints_RegistrationOrder.xml::20201128181606-2::jhipster:
Reason: liquibase.exception.DatabaseException: Referential integrity constraint violation: "FK_REGISTRATION_ORDER_STUDENT_ID: PUBLIC.REGISTRATION_ORDER FOREIGN KEY(STUDENT_ID) REFERENCES PUBLIC.STUDENT(ID)"; SQL statement:
ALTER TABLE PUBLIC.registration_order ADD CONSTRAINT fk_registration_order_student_id FOREIGN KEY (student_id) REFERENCES PUBLIC.student (id) [23506-200] [Failed SQL: (23506) ALTER TABLE PUBLIC.registration_order ADD CONSTRAINT fk_registration_order_student_id FOREIGN KEY (student_id) REFERENCES PUBLIC.student (id)]
at liquibase.changelog.ChangeSet.execute(ChangeSet.java:646)
at liquibase.changelog.visitor.UpdateVisitor.visit(UpdateVisitor.java:53)
at liquibase.changelog.ChangeLogIterator.run(ChangeLogIterator.java:83)
at liquibase.Liquibase.update(Liquibase.java:202)
at liquibase.Liquibase.update(Liquibase.java:179)
at liquibase.integration.spring.SpringLiquibase.performUpdate(SpringLiquibase.java:366)
at liquibase.integration.spring.SpringLiquibase.afterPropertiesSet(SpringLiquibase.java:314)
at org.springframework.boot.autoconfigure.liquibase.DataSourceClosingSpringLiquibase.afterPropertiesSet(DataSourceClosingSpringLiquibase.java:46)
at io.github.jhipster.config.liquibase.AsyncSpringLiquibase.initDb(AsyncSpringLiquibase.java:118)
at io.github.jhipster.config.liquibase.AsyncSpringLiquibase.lambda$afterPropertiesSet$0(AsyncSpringLiquibase.java:93)
at io.github.jhipster.async.ExceptionHandlingAsyncTaskExecutor.lambda$createWrappedRunnable$1(ExceptionHandlingAsyncTaskExecutor.java:78)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
My JDL is:
entity Student {
birthDate LocalDate
nickName String maxlength(50)
}
entity RegistrationOrder{
paymentAmount BigDecimal required min(0)
materialFee BigDecimal required min(0)
placedDate Instant required
}
relationship OneToOne {
Student{user(login) required} to User with jpaDerivedIdentifier
}
relationship ManyToOne {
RegistrationOrder{student required} to Student
}
If I removed "with jpaDerivedIdentifier", the Jhipster app started without error. Any idea?

Probably because there are already some data loaded from CSV by Liquibase that violate the foreign key you add in your migration. Either change the data in the CSV files or change the order of migrations.
The fact that you're sharing an id with User does not help of course because the User table is created and loaded in first migration.

Related

why migration is required during editing enum in prisma schema

enum OrderStatus {
paymentDone
OrderCreated
OrderConfirmed
}
iam using prima postgres db
if you add an extra literal orderCancelled in prisma schema it is asking for creating a new migration , why it behaves like this ?
This is the expected behaviour.
Initially when the enum had 3 values, this migration script would have been executed.
CREATE TYPE "OrderStatus" AS ENUM ('paymentDone', 'OrderCreated', 'OrderConfirmed');
When you are adding a new enum OrderCancelled, the OrderStatus type needs to be altered like this.
ALTER TYPE "OrderStatus" ADD VALUE 'OrderCancelled';
So Prisma Migrate initiating a new migration is the correct behavior.

MikroORM: How to use 'insert_id' for subsequent persists?

How can I get the insert_id (or existing id on duplicate key error) from a persist? I'd like to use it in following persists before flush.
In my mind, even though the EntityManager doesn't have an id yet, it could still populate that and use it during flush, but I think my thinking is flawed here, I'm new to MikroORM. From what I can see in the docs, I can only achieve this using the Query Builder.
Thanks for your help!
You can just build the entity graph, the entity does not need to have a PK to be used in a relation:
const book = new Book(); // new entity, no PK
user.favorites.push(book); // doesnt matter if it has PK
await em.flush(); // if `user` was a managed entity, this will find the new book and save it to the database
console.log(book.id); // now we have the PK available on entity
In other words, the entity instance is what holds the identity, you use that, not the PK.

Spring Data Cassandra codec not found for requested operation set<varchar> <-> java.util.Set

My entity has a field
#Column("authorizations")
#Builder.Default
private Map<String, Set<String>> authorizations = new HashMap<>();
When I query for that object via Spring Data repository I'm getting an exception
CodecNotFoundException: Codec not found for requested operation:
[set <-> java.util.Set]
Writes work just fine though. I can't believe this is not supported out of the box.
Table definition
CREATE TABLE resource_authorization_rules(
resource text,
region text,
authorizations map<text, frozen<set<text>>>,
PRIMARY KEY (resource, region)
);
Probably something with type erasure. How to tackle this with least effort?
This is a limitation of the the Spring Data Casasndra. There is a JIRA for improving support of frozen collections. And it looks like that it could be worked around with custom row mapper as described here.
P.S. The DataStax Java Driver has corresponding annotations in their object mapper.

How to get entity without specifying its ancestor?

I am using Google Cloud node.js gcloud library and trying to get an entity that was saved with ancestor key.
To my surprised, I am not able to get the entity without specifying its ancestor key.
const ds = gcloud.datastore.dataset(config);
...
ds.get(key, (err, entity)=>{
return entity;
});
The unique identifier for your entity is the full path, the id/name of the entity is not globally unique.
As an example, let's assume you were modelling a basic file system that has folders and files. Folders are the parent entities and files are the child entities. You might for example have data like:
File Entity: name='readme.txt', ancestor=['Folder', 'getting-started']
File Entity: name='readme.txt', ancestor=['Folder', 'third-party-libs']
Without specifying the ancestor, the system cannot disambiguate which 'readme.txt' you are trying to reference.

How to EF code first fluent API string primary key?

I tried to make a primary key for Member entity, I don't want to use annotation, just use fluent API:
Member{
public string MemberID {get;set;}
...
}
In MemberMapping
this.hasKey(t=>t.MemberID);
When update database I got this error:
Identity column 'MemberID' must be of data type int, bigint, smallint, tinyint, or decimal or numeric with
a scale of 0, and constrained to be nonnullable
EF supports string as PK but you have to set explicitly that property with some value when you need to create an Member's instance and save it into your DB. The only type that is identity by default in EF is int. To fix your problem I think you have two options:
Change the MemberID column in your database to not be Identity. That should solve the problem.
If you want that EF do that change for you then add this configuration:
this.hasKey(t=>t.MemberID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
Create a new migration using the Add-Migration command and try to run again Update-Database command.
Now,if your MemberID column in your DB isn't Identity and you are trying to set as Identity the MemberID PK property in your model, that also could be the cause of your issue. If that is the case, remove that configuration and try to run again Update-Database command.
From Programming Entity Framework Code First book, page 44:
In the case where the Key field is an Integer, Code First defaults to
DatabaseGeneratedOption.Identity. With a Guid, you need to explicitly
configure this. These are the only types that you can configure to be
Identity when Code First is generating the database.
the problem is not the PK but the indentity. You should have something like
property(x => x.MemberID).HasDatabaseGeneratedOption(
DatabaseGeneratedOption.None);

Resources