I have the below JDL that I am using to create the jhipster application.
entity AuthClient(auth_client) {
msisdn String required maxlength(255),
email String required unique maxlength(255),
password String required maxlength(255),
lastLogin Instant,
createdAt Instant required,
createdBy Integer,
updatedAt Instant,
updatedBy Integer,
isDeleted Boolean required,
deletedAt Instant,
deletedBy Integer
}
entity AuthToken(auth_token) {
token String required maxlength(255),
appId Integer required,
appVersionName String maxlength(255),
clientId Integer required,
}
entity ClientProfile(client_profile) {
fName String required maxlength(255),
mName String maxlength(255),
lName String required maxlength(255),
gender Integer,
clientId Integer required
}
// Relations
relationship OneToMany {
AuthClient{AuthToken(clientId)} to AuthToken{AuthClient}
}
relationship OneToOne{
ClientProfile{AuthClient} to AuthClient{ClientProfile(clientId)},
}
// Options
service * with serviceClass
paginate * with pagination
dto * with mapstruct
filter *
However, instead of using the variable clientId as the foreign key it creates another field in the database.
I need to use the clientId as the foreign key in this application and not the generated new field Auth Client
Defining a clientId field as you did has no impact on the relationship, these are two separate things.
When you define a relationship, a field is automatically created in the entity and its type is of the related class: it's a reference to an object in the java entity and a foreign key column in the database table.
By default, the foreign key column will be named as auth_client_id and the field will be named as authClient. However, the JDL syntax for relationships lets you configure the relationship name and so modify the generated names.
So, remove all the clientId fields and modify your relationships definitions as follows:
// Relations
relationship OneToMany {
AuthClient to AuthToken{client}
}
relationship OneToOne{
ClientProfile{client} to AuthClient
}
This way you get the foreign key column named as client_id and the field named as client.
You can then define also which field of the related entity will be used for display in the generated UI.
There is more to learn about relationships in the doc: https://www.jhipster.tech/jdl/relationships
Related
Use case is simple:
users table
sessions table
Each user can be logged in multiple places therefore they can have multiple sessions -> one to many relationship. in SQL this isn't a big deal/problem, but the generated types available in #prisma/client create a weird type when it comes to the input models.
I'm using NestJS and need TS models based on classes that exist at runtime, so I can make use of decorators on keys for input validation and graphql usage.
I'm creating a model based off of the Prisma.SessionCreateInput coming from #prisma/client.
prisma schema:
model User {
id String #id #default(uuid())
...
sessions Session[]
}
model Session {
id String #id #default(uuid())
user User #relation(fields: [userId], references: [id])
userId String
}
The TS model:
import { Prisma } from '#prisma/client';
export class SessionModel implements Prisma.SessionCreateInput {
id?: string;
userId?: string;
user: Prisma.UserCreateNestedOneWithoutSessionsInput;
}
Now I'm defining the type for user explicitly based on what Prisma is telling me to, in my opinion I don't need any user data there when creating a session, merely the userId.
UserCreateNestedOneWithoutSessionsInput:
type Prisma.UserCreateNestedOneWithoutSessionsInput = {
create?: (Prisma.Without<Prisma.UserCreateWithoutSessionsInput, Prisma.UserUncheckedCreateWithoutSessionsInput> & Prisma.UserUncheckedCreateWithoutSessionsInput) | (Prisma.Without<...> & Prisma.UserCreateWithoutSessionsInput);
connectOrCreate?: Prisma.UserCreateOrConnectWithoutSessionsInput;
connect?: Prisma.UserWhereUniqueInput;
}
which seems some sort of meta type that I very much do not need?
How can I maintain type safety and have these derived TS classes to work with?
Is there a way so all foreign key generated follows underscore user_id instead of camelCase userId.
Is there a way to configure TypeORM so I don't have to think about it when define the relation.
`userId` varchar(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL
Yes this is possible by specifiying name property when you define your column like such (see all possible options here https://typeorm.io/#/entities/column-options):
#Column('int', { 'name': 'user_id' })
userId: number
The database field will then be user_id but when accessing the entity it will be mapped back to userId
I'm new to jhipster. so I'm sorry if the answer is obvious.
I'm trying to import my JDL with the command :
import-jdl ~/Downloads/jhipster-jdl.jh --debug
my JDL:
entity Package{
origin String,
destination String,
amORpm String,
department Integer,
weight Long,
barcode Long
}
entity Supplier {
regionName String required
}
entity Mission{
dueDate Instant required
}
entity Seller {
streetAddress String,
postalCode String,
city String,
stateProvince String,
phoneNumber String
}
entity WareHouse{
regionName String
}
entity Timer {
firstName String,
lastName String,
email String,
phoneNumber String,
hiringDate Instant required
}
entity GraphDataWeight {
effort Long
}
relationship OneToOne{
Mission {missionId} to Package
}
relationship OneToMany {
Supplier {packageId} to Package
Seller {sellerId} to Mission
Timer {timerId} to Mission
WareHouse {timerId} to Timer
GraphDataWeight {sellerId1} to Seller
GraphDataWeight {sellerId2} to Seller
}
paginate all with infinite-scroll
paginate all with pagination
dto * with mapstruct
Set service options to all except few
service all with serviceImpl
Set an angular suffix
angularSuffix * with mySuffix
the error I get:
The JDL is being parsed.
DEBUG! Error:
Error: The entity must be valid in order to be added.
Errors: The entity name cannot be a reserved keyword
tried all options that I found to fix it but I get the same error
at the begging I had an enum but I changed it just to get it to work. but I still get this error
I don't see any reserved words that I know of
thanks in advance for ur time
You cannot call an entity Package since it is a reserved keyword.
You also need to remove or comment out Set service options to all except few and Set an angular suffix to make it work.
In a sails project, considering a model User and a model Role, with a relationship between User and Role :
// `User.js
module.exports = {
attributes: {
...
roles: {
collection: 'role',
dominant: true
},
...
}
}
For the the database representation, sails/waterline will create following tables :
table user,
table role,
table like user_roles__role_roles_role to represent the collection
I know we can force the name for the models USER and ROLE
(with the property 'tablename' : http://sailsjs.com/documentation/concepts/models-and-orm/attributes).
But how can we force the name the relationship table ? (Especially this name is quite long and tends to exceed limit).
Assuming this is a two-way relationship, and the Role model has a users collection, Sails will expect a table named role_users__user_roles, which has the role id first, user id second.
Your example table name would require User to be dominant and would require the Role model to have an attribute named roles_role that is a User collection.
To create your own join table, you can use the through association method and add a new model that represents the relationship, perhaps UsersRoles, and specify the tableName in that model definition.
Examples of the through association:
sails
docs
similar question
gist from comments in that question
I'm trying to create a hierarchical folder structure. Here's my Folder entity:
$ yo jhipster:entity Folder
The entity Folder is being created.
Generating field #1
? Do you want to add a field to your entity? Yes
? What is the name of your field? name
? What is the type of your field? String
? Do you want to add validation rules to your field? No
=================Folder=================
name (String)
Generating field #2
? Do you want to add a field to your entity? Yes
? What is the name of your field? parentId
? What is the type of your field? Long
? Do you want to add validation rules to your field? No
=================Folder=================
name (String)
parentId (Long)
Generating field #3
? Do you want to add a field to your entity? No
=================Folder=================
name (String)
parentId (Long)
I'm trying to map out just what I need to provide jhipster's entity generator to make it work. This is what I have so far...
Generating relationships with other entities
? Do you want to add a relationship to another entity? Yes
? What is the name of the other entity? Folder
? What is the name of the relationship? parent
? What is the type of the relationship? one-to-many
? What is the name of this relationship in the other entity? child
Am I on the right track? How do I create the child many-to-one relationship? I get a warning if I try to create it with the Folder entity. There's no way to generate it afterwards.
You can use https://jhipster.github.io/jdl-studio/ for writing as jdl for creating entities.
Please visit https://jhipster.github.io/jhipster-uml/#jdl for more information.
This is a sample JDL that has relationship to itself :
entity RankProperties {
rank Integer required,
minExp Integer required,
maxExp Integer required,
maxStamina Integer required,
maxAlly Integer required,
maxTeam Integer required
}
enum TaskMode {
NO_CONTINUE_STAGE_COUNT,
STAGE_COUNT,
STAGE_ID
}
entity Task {
taskMode TaskMode required,
value Integer required
}
relationship ManyToOne {
Task{parent} to Task
}
dto all with mapstruct
service all with serviceClass
I recommend to use jdl model.
entity A { property1 String }
relationship OneToMany {
A{sons} to A{parent}
}
The model generates a Entity java class like (some annotations ignored):
class A {
#OneToMany(mappedBy="parent")
private Set<A> sons = new HashSet<>();
#ManyToOne
private A parent;
}