jhipster / generator-jhipster-nodejs

A NodeJS blueprint that creates the backend using NestJS
https://www.npmjs.com/package/generator-jhipster-nodejs
Apache License 2.0
257 stars 81 forks source link

A relation OneToOne from a custom entity to the User entity together other OneToMany relationships throw an error #195

Closed hmarchadour closed 3 years ago

hmarchadour commented 3 years ago

Describe the bug As soon as an entity "bind" the User entity thanks to a OneToOne relation, all OneToMany relation are generated without the other annotation property.

To Reproduce Steps to reproduce the behavior:

  1. Generate thanks to the JDL
  2. try to build :
    
    ./server/node_modules/ts-node/src/index.ts:240
    return new TSError(diagnosticText, diagnosticCodes)
           ^
    TSError: ⨯ Unable to compile TypeScript:
    src/domain/a.entity.ts:18:6 - error TS2554: Expected 2-3 arguments, but got 1.

18 @OneToMany(type => B)



  node_modules/typeorm/decorator/relations/OneToMany.d.ts:6:102
    6 export declare function OneToMany<T>(typeFunctionOrTarget: string | ((type?: any) => ObjectType<T>), inverseSide: string | ((object: T) => any), options?: RelationOptions): PropertyDecorator;
``` 

in ./server/src/domain/a.entity.ts
```
@Entity('a')
export class A extends BaseEntity {
    @OneToOne(type => User)
    @JoinColumn()
    user: User;

    @OneToMany(type => B)
    bs: B[];
}
```

**Expected behavior**
in ./server/src/domain/a.entity.ts
```
@Entity('a')
export class A extends BaseEntity {
    @OneToOne(type => User)
    @JoinColumn()
    user: User;

    @OneToMany(
        type => B,
        other => other.a
    )
    bs: B[];
}
```
**Screenshots**

**Desktop (please complete the following information):**

-   OS: MacOS
-   Browser chrome
-   Version Latest

**NHipster configuration**

```
test@0.0.1-SNAPSHOT */jdl/test
├── generator-jhipster@6.8.0 
└─┬ generator-jhipster-nodejs@1.4.0
  └── generator-jhipster@6.8.0  deduped

```

##### **JHipster configuration, a `.yo-rc.json` file generated in the root folder**

<details>
<summary>.yo-rc.json file</summary>
<pre>
{
  "generator-jhipster": {
    "authenticationType": "jwt",
    "cacheProvider": "no",
    "clientFramework": "react",
    "serverPort": "8081",
    "serviceDiscoveryType": false,
    "skipUserManagement": false,
    "baseName": "test",
    "buildTool": "maven",
    "databaseType": "sql",
    "devDatabaseType": "sqlite",
    "enableHibernateCache": false,
    "enableSwaggerCodegen": false,
    "enableTranslation": true,
    "jhiPrefix": "jhi",
    "languages": ["en", "fr"],
    "messageBroker": false,
    "nativeLanguage": "fr",
    "prodDatabaseType": "mysql",
    "searchEngine": false,
    "skipClient": false,
    "testFrameworks": ["protractor"],
    "websocket": false,
    "applicationType": "monolith",
    "packageName": "com.jhipster.node",
    "packageFolder": "com/jhipster/node",
    "clientPackageManager": "yarn",
    "blueprint": "generator-jhipster-nodejs",
    "jhipsterVersion": "6.8.0",
    "creationTimestamp": 1609178340997,
    "skipServer": false,
    "clientTheme": "none",
    "clientThemeVariant": "",
    "useSass": true,
    "jwtSecretKey": "bXktc2VjcmV0LXRva2VuLXRvLWNoYW5nZS1pbi1wcm9kdWN0aW9uLWFuZC10by1rZWVwLWluLWEtc2VjdXJlLXBsYWNl",
    "embeddableLaunchScript": false,
    "entitySuffix": "",
    "dtoSuffix": "DTO",
    "otherModules": [
      {
        "name": "generator-jhipster-nodejs",
        "version": "1.4.0"
      }
    ],
    "blueprints": [
      {
        "name": "generator-jhipster-nodejs",
        "version": "1.4.0"
      }
    ]
  },
  "entities": ["A", "B"]
}

</pre>
</details>

##### **JDL for the Entity configuration(s) `entityName.json` files generated in the `.jhipster` directory**

<details>
<summary>JDL entity definitions</summary>

<pre>
entity A
entity B
relationship OneToOne {
  A{user} to User
}
relationship OneToMany {
  A{b} to B{a}
}

</pre>
</details>

##### **Environment and Tools**

java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)

git version 2.19.0

node: v14.15.3

npm: 6.14.9

yeoman: 3.1.1

yarn: 1.22.10

Docker version 19.03.13, build 4484c46d9d

docker-compose version 1.27.4, build 40524192

**Additional context**
Noting
ghost commented 3 years ago

I have tried to replicate your issue with my jdl on https://github.com/jhipster/generator-jhipster-nodejs/blob/feature/user-onetomany-issue195/test-integration/samples/microservice-oauth2-jdl/microservice-oauth2-jdl.jdl .

So I have a lot of OneToMany relationship and a OneToOne for the ShopUser and User entity. But I haven't compilation error: https://github.com/jhipster/generator-jhipster-nodejs/runs/1621025748

hmarchadour commented 3 years ago

Thanks for your feedback. Interesting... Have you any diff in node/yeoman...?

hmarchadour commented 3 years ago

This is a generation behavior, I think to the yeoman release. I will try with https://github.com/jhipster/generator-jhipster-nodejs/blob/feature/user-onetomany-issue195/test-integration/samples/microservice-oauth2-jdl/microservice-oauth2-jdl.jdl ;)

ghost commented 3 years ago

Thanks!

hmarchadour commented 3 years ago

I have tried to replicate your issue with my jdl on https://github.com/jhipster/generator-jhipster-nodejs/blob/feature/user-onetomany-issue195/test-integration/samples/microservice-oauth2-jdl/microservice-oauth2-jdl.jdl .

So I have a lot of OneToMany relationship and a OneToOne for the ShopUser and User entity.

If I'm right, I don't find any relation OneToMany from ShopUser to another entity in https://github.com/jhipster/generator-jhipster-nodejs/blob/feature/user-onetomany-issue195/test-integration/samples/microservice-oauth2-jdl/microservice-oauth2-jdl.jdl

//...

entity ShopUser {
    preference String
}

relationship OneToOne {
  ShopUser{shop} to User
}

relationship OneToMany {
    Customer{wishList(title)} to WishList{customer},
    WishList{product(title)} to Product{wishList},
    Customer{address} to Address{customer}
}

relationship ManyToOne {
    Category{parent} to Category
}

relationship ManyToMany {
    Category{product(title)} to Product{category}
}

To test my use case, I add a meaningless relation from ShopUser to Product :

relationship OneToMany {
    ShopUser{products} to Product
}

After a

  1. nhipster import-jdl ./test.jh --force
  2. fix an error in /src/main/webapp/app/shared/model/category.model.ts I delete this import import { ICategory } from 'app/shared/model/category.model';
  3. yarn run start:app
/server/node_modules/ts-node/src/index.ts:240
    return new TSError(diagnosticText, diagnosticCodes)
           ^
TSError: ⨯ Unable to compile TypeScript:
src/domain/shop-user.entity.ts:21:6 - error TS2554: Expected 2-3 arguments, but got 1.

21     @OneToMany(type => Product)
        ~~~~~~~~~~~~~~~~~~~~~~~~~~

  node_modules/typeorm/decorator/relations/OneToMany.d.ts:6:102
    6 export declare function OneToMany<T>(typeFunctionOrTarget: string | ((type?: any) => ObjectType<T>), inverseSide: string | ((object: T) => any), options?: RelationOptions): PropertyDecorator;
                                                                                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
hmarchadour commented 3 years ago

server/src/domain/shop-user.entity.ts

/* eslint-disable @typescript-eslint/no-unused-vars */
import { Entity, Column, JoinColumn, OneToOne, ManyToOne, OneToMany, ManyToMany, JoinTable } from 'typeorm';
import { BaseEntity } from './base/base.entity';

import { Product } from './product.entity';

import { User } from './user.entity';

/**
 * A ShopUser.
 */
@Entity('shop_user')
export class ShopUser extends BaseEntity {
    @Column({ name: 'preference', nullable: true })
    preference: string;

    @OneToOne(type => User)
    @JoinColumn()
    shop: User;

    @OneToMany(type => Product)
    products: Product[];

    // jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
}
One-to-many relation allows to create type of relation when Entity1 can have multiple instances of Entity2. Entity2 have only one Entity1. Entity2 is an owner of the relationship, and storages Entity1 id on its own side.

Expected 2-3 arguments, but got 1.ts(2554
hmarchadour commented 3 years ago
JHipster Version(s)
test@0.0.1-SNAPSHOT */test2
├── generator-jhipster@6.8.0 
└─┬ generator-jhipster-nodejs@1.4.0
  └── generator-jhipster@6.8.0  deduped
JHipster configuration, a .yo-rc.json file generated in the root folder
.yo-rc.json file
{
  "generator-jhipster": {
    "authenticationType": "jwt",
    "cacheProvider": "no",
    "clientFramework": "react",
    "serverPort": "8081",
    "serviceDiscoveryType": false,
    "skipUserManagement": false,
    "baseName": "test",
    "buildTool": "maven",
    "databaseType": "sql",
    "devDatabaseType": "sqlite",
    "enableHibernateCache": false,
    "enableSwaggerCodegen": false,
    "enableTranslation": true,
    "jhiPrefix": "jhi",
    "languages": ["en", "fr"],
    "messageBroker": false,
    "nativeLanguage": "fr",
    "prodDatabaseType": "mysql",
    "searchEngine": false,
    "skipClient": false,
    "testFrameworks": ["protractor"],
    "websocket": false,
    "applicationType": "monolith",
    "packageName": "com.jhipster.node",
    "packageFolder": "com/jhipster/node",
    "clientPackageManager": "npm",
    "blueprint": "generator-jhipster-nodejs",
    "jhipsterVersion": "6.8.0",
    "creationTimestamp": 1609243620779,
    "skipServer": false,
    "clientTheme": "none",
    "clientThemeVariant": "",
    "useSass": true,
    "jwtSecretKey": "bXktc2VjcmV0LXRva2VuLXRvLWNoYW5nZS1pbi1wcm9kdWN0aW9uLWFuZC10by1rZWVwLWluLWEtc2VjdXJlLXBsYWNl",
    "embeddableLaunchScript": false,
    "entitySuffix": "",
    "dtoSuffix": "DTO",
    "otherModules": [
      {
        "name": "generator-jhipster-nodejs",
        "version": "1.4.0"
      }
    ],
    "blueprints": [
      {
        "name": "generator-jhipster-nodejs",
        "version": "1.4.0"
      }
    ]
  },
  "entities": ["Category", "Product", "Customer", "Address", "WishList", "ShopUser"]
}

JDL for the Entity configuration(s) entityName.json files generated in the .jhipster directory
JDL entity definitions
entity Category {
  description String required,
  sortOrder Integer,
  dateAdded LocalDate,
  dateModified LocalDate,
  status CategoryStatus
}
entity Product {
  title String required,
  keywords String,
  description String,
  rating Integer,
  dateAdded LocalDate,
  dateModified LocalDate
}
entity Customer {
  firstName String,
  lastName String,
  email String,
  telephone String
}
entity Address {
  address1 String,
  address2 String,
  city String,
  postcode String required maxlength(10),
  country String required maxlength(2)
}
entity WishList {
  title String required,
  restricted Boolean
}
entity ShopUser {
  preference String
}
enum CategoryStatus {
  AVAILABLE,
  RESTRICTED,
  DISABLED
}

relationship OneToOne {
  ShopUser{shop} to User
}
relationship OneToMany {
  ShopUser{products} to Product{shopUser},
  WishList{product} to Product{wishList},
  Customer{address} to Address{customer},
  Customer{wishList} to WishList{customer}
}
relationship ManyToOne {
  Category{parent} to Category
}
relationship ManyToMany {
  Category{product(title)} to Product{category}
}

paginate Category, Customer, Address with pagination
paginate Product with infinite-scroll
service Category with serviceClass

Environment and Tools

java version "1.7.0_79" Java(TM) SE Runtime Environment (build 1.7.0_79-b15) Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)

git version 2.19.0

node: v14.15.3

npm: 6.14.9

yeoman: 3.1.1

yarn: 1.22.10

Docker version 19.03.13, build 4484c46d9d

docker-compose version 1.27.4, build 40524192

ghost commented 3 years ago

Yes, thanks for the feedback, I have performed the fix!!

hmarchadour commented 3 years ago

Note: the only way that I've found to deal with an user relation :

entity PrivateUser {
    login String
}

relationship ManyToOne {
    PrivateUser{user(login)} to User
}
ghost commented 3 years ago

Note: the only way that I've found to deal with an user relation :

entity PrivateUser {
    login String
}

relationship ManyToOne {
    PrivateUser{user(login)} to User
}

Yes, the bug was only in the OneToMany