Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue on Front side when using skipClient for some entities #13305

Closed
DanielFran opened this issue Dec 16, 2020 · 22 comments · Fixed by #14461
Closed

Issue on Front side when using skipClient for some entities #13305

DanielFran opened this issue Dec 16, 2020 · 22 comments · Fixed by #14461

Comments

@DanielFran
Copy link
Member

DanielFran commented Dec 16, 2020

Overview of the issue

Issue with declaration of model on front for entities that have been skipped

Motivation for or Use Case

On front-end, it is declared model for all one-to-many entities but some of them are defined to be 'skipped' on the front side.

[INFO] ERROR Failed to compile with 1 errors12:11:41
[INFO]
[INFO] error
[INFO]
[INFO] src/main/webapp/app/entities/symptom/symptom.model.ts:1:31 - error TS2307: Cannot find module 'app/entities/toxicity-rate/toxicity-rate.model' or its corresponding type declarations.
[INFO]
[INFO] 1 import { IToxicityRate } from 'app/entities/toxicity-rate/toxicity-rate.model';
[INFO] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[INFO] src/main/webapp/app/entities/drug/drug.model.ts:1:25 - error TS2307: Cannot find module 'app/entities/notice/notice.model' or its corresponding type declarations.
[INFO]
[INFO] 1 import { INotice } from 'app/entities/notice/notice.model';
[INFO] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

JHipster Version(s)

Using main branch.

JHipster configuration
JHipster Version(s)
supportivecare@1.2.0-SNAPSHOT C:\REDCATS\Mestrado UC\3 Semestre\Studio\MSE-2019-2021\support_care
+-- generator-jhipster@6.10.5
`-- generator-jhipster-entity-audit@3.3.0
  `-- generator-jhipster@6.10.5  deduped

JHipster configuration, a .yo-rc.json file generated in the root folder
.yo-rc.json file
{
  "generator-jhipster": {
    "authenticationType": "jwt",
    "cacheProvider": "caffeine",
    "clientFramework": "angularX",
    "serverPort": "8080",
    "serviceDiscoveryType": false,
    "skipUserManagement": false,
    "withAdminUi": false,
    "baseName": "supportivecare",
    "buildTool": "maven",
    "databaseType": "sql",
    "devDatabaseType": "h2Memory",
    "enableHibernateCache": true,
    "enableSwaggerCodegen": false,
    "enableTranslation": true,
    "jhiPrefix": "custom",
    "languages": ["pt-pt", "en"],
    "messageBroker": false,
    "prodDatabaseType": "postgresql",
    "searchEngine": false,
    "skipClient": false,
    "testFrameworks": ["cypress"],
    "websocket": false,
    "applicationType": "monolith",
    "packageName": "uc.dei.mse.supportivecare",
    "packageFolder": "uc/dei/mse/supportivecare",
    "clientPackageManager": "npm",
    "nativeLanguage": "pt-pt",
    "jhipsterVersion": "6.10.5",
    "skipServer": false,
    "dtoSuffix": "DTO",
    "entitySuffix": "",
    "reactive": false,
    "clientTheme": "none",
    "clientThemeVariant": "",
    "entities": [
      "Administration",
      "Notice",
      "Drug",
      "Treatment",
      "TherapeuticRegime",
      "Document",
      "Content",
      "Outcome",
      "ToxicityRate",
      "Symptom",
      "Feedback"
    ],
    "skipCheckLengthOfIdentifier": false,
    "skipFakeData": false,
    "blueprints": [],
    "otherModules": [],
    "pages": [],
    "creationTimestamp": 1608113073245,
    "jwtSecretKey": "YourJWTSecretKeyWasReplacedByThisMeaninglessTextByTheJHipsterInfoCommandForObviousSecurityReasons",
    "lastLiquibaseTimestamp": 1608113733000
  },
  "generator-jhipster-entity-audit": {
    "auditFramework": "custom",
    "auditPage": false,
    "lastLiquibaseTimestamp": 1608113656000
  }
}
JDL for the Entity configuration(s) entityName.json files generated in the .jhipster directory
JDL entity definitions
/**
 * Administração.
 */
entity Administration {
  /**
   * Tipo de administração.
   */
  type String required maxlength(100)
}
/**
 * Observação.
 */
entity Notice {
  /**
   * Descrição.
   */
  description String required maxlength(1000),
  /**
   * Avaliação.
   */
  evaluation String required maxlength(1000),
  /**
   * Intervenção interdependente.
   */
  intervention String required maxlength(1000)
}
/**
 * Medicamento.
 */
entity Drug {
  /**
   * Nome.
   */
  name String required maxlength(250),
  /**
   * Descrição geral.
   */
  description String maxlength(1000)
}
/**
 * Tratamento.
 */
entity Treatment {
  /**
   * Tipo de tratamento.
   */
  type String required maxlength(100)
}
/**
 * Regime Terapêutico.
 */
entity TherapeuticRegime {
  /**
   * Nome.
   */
  name String required maxlength(250),
  /**
   * Acrônimo.
   */
  acronym String maxlength(50),
  /**
   * Propósito.
   */
  purpose String required maxlength(1000),
  /**
   * Condições para administração.
   */
  condition String required maxlength(1000),
  /**
   * Calendarização.
   */
  timing String maxlength(250),
  /**
   * Indicação para prescrição.
   */
  indication String required maxlength(1000),
  /**
   * Critérios de redução de dose.
   */
  criteria String required maxlength(1000),
  /**
   * Outras informações.
   */
  notice String maxlength(1000)
}
/**
 * Documento.
 */
entity Document {
  /**
   * Título.
   */
  title String required maxlength(250),
  /**
   * Tamanho.
   */
  size Long required,
  /**
   * Tipo de ficheiro.
   */
  mimeType String maxlength(50)
}
/**
 * Conteúdo.
 */
entity Content {
  /**
   * Dados.
   */
  data AnyBlob required
}
/**
 * PROM.
 */
entity Outcome {
  /**
   * Nome.
   */
  name String required maxlength(250),
  /**
   * Descrição.
   */
  description String maxlength(1000)
}
/**
 * Grau de Toxicidade.
 */
entity ToxicityRate {
  /**
   * Nome.
   */
  name String required maxlength(250),
  /**
   * Descrição.
   */
  description String maxlength(1000),
  /**
   * Informação ao doente.
   */
  notice String maxlength(1000),
  /**
   * Intervenção autónoma.
   */
  autonomousIntervention String maxlength(1000),
  /**
   * Intervenção interdependente.
   */
  interdependentIntervention String maxlength(1000),
  /**
   * Suporte para auto-gestão.
   */
  selfManagement String maxlength(1000)
}
/**
 * Sintoma (Efeito secundário).
 */
entity Symptom {
  /**
   * Nome.
   */
  name String required maxlength(250),
  /**
   * Informação ao enfermeiro.
   */
  notice String maxlength(1000)
}
/**
 * Feedback.
 */
entity Feedback {
  /**
   * Nome da entidade.
   */
  entityName EntityFeedback required,
  /**
   * Id da entidade.
   */
  entityId Long required,
  /**
   * Polegar.
   */
  thumb Boolean required,
  /**
   * Razão.
   */
  reason String maxlength(1000),
  /**
   * Resolvido.
   */
  solved Boolean required,
  /**
   * Anónimo.
   */
  anonym Boolean required
}
enum EntityFeedback {
  DRUG (Drug),
  THERAPEUTIC_REGIME (TherapeuticRegime),
  OUTCOME (Outcome),
  SYMPTOM (Symptom)
}

relationship OneToOne {
  Document{content} to Content{document required}
}
relationship OneToMany {
  Drug{notice(description)} to Notice{drug(name) required},
  Administration{drug} to Drug{administration(type) required},
  Treatment{therapeuticRegime} to TherapeuticRegime{treatment(type) required},
  Outcome{document} to Document{outcome(name) required},
  Symptom{toxicityRate(name)} to ToxicityRate{symptom(name)}
}
relationship ManyToMany {
  TherapeuticRegime{drug(name)} to Drug{therapeuticRegime(name)},
  Symptom{therapeuticRegime(name)} to TherapeuticRegime{symptom(name)},
  Symptom{outcome(name)} to Outcome{symptom(name)}
}

dto Administration, Notice, Drug, Treatment, TherapeuticRegime, Document, Content, Outcome, ToxicityRate, Symptom, Feedback with mapstruct
paginate Administration, Notice, Drug, Treatment, TherapeuticRegime, Document, Content, Outcome, ToxicityRate, Symptom, Feedback with infinite-scroll
service Administration, Notice, Drug, Treatment, TherapeuticRegime, Document, Content, Outcome, ToxicityRate, Symptom, Feedback with serviceClass
filter Administration, Notice, Drug, Treatment, TherapeuticRegime, Document, Content, Outcome, ToxicityRate, Symptom, Feedback

Environment and Tools

java version "11.0.8" 2020-07-14 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.8+10-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.8+10-LTS, mixed mode)

git version 2.24.1.windows.2

node: v14.15.1

npm: 6.14.9

yeoman: 3.1.1

Docker version 20.10.0, build 7287ab3

docker-compose version 1.27.4, build 40524192

identical .jhipster\Administration.json
identical .jhipster\Content.json
identical .jhipster\Document.json
identical .jhipster\Drug.json
identical .jhipster\Feedback.json
identical .jhipster\Notice.json
identical .jhipster\Outcome.json
identical .jhipster\Symptom.json
identical .jhipster\TherapeuticRegime.json
identical .jhipster\ToxicityRate.json
identical .jhipster\Treatment.json
INFO! Congratulations, JHipster execution is complete!- [ ] Checking this box is mandatory (this is just to show you read everything)

@DanielFran
Copy link
Member Author

DanielFran commented Dec 16, 2020

@kaidohallik @mshima
Do not know if it is related with Angular only and the refactoring, or related with changes on entities....

Issue related with:

relationship OneToMany {
Drug{notice(description)} to Notice{drug(name) required},
Symptom{toxicityRate(name)} to ToxicityRate{symptom(name)}
}

And in original jdl I have also declared to skip some entities:
skipClient Notice, ToxicityRate

But on the 'jhipster info' it did not appears!

@kaidohallik
Copy link
Contributor

I tried the same config with Vue. Vue compiles successfully, but the same error occurs in runtime in Vue after entering to page that includes this import, this model is not generated also in Vue client.
So seems that general problem, not related to Angular.

@mshima
Copy link
Member

mshima commented Dec 16, 2020

If the jdl works on jhipster 6, then it’s because of the flatten dto.
At jhipster 7, entities always depends on the model of the other entity.
Drug is not skipClient but it uses notice model that is skipClient. In this case at least the model file must be written.

@mshima
Copy link
Member

mshima commented Dec 16, 2020

In this case we should try to support single side relationships:


relationship ManyToOne {
Notice{drug(name) required} to Drug,
ToxicityRate{symptom(name)} to Symptom
}

And drop back reference.

@mshima
Copy link
Member

mshima commented Dec 16, 2020

cc @MathieuAA

@kaidohallik
Copy link
Contributor

FYI: if I look at Vue source then there is also used .service file for skipClient entity, so for Vue also .service file is needed.

@pascalgrimaud
Copy link
Member

After discussing with @MathieuAA about this, here my opinion:

  • there is no bug here, as it's the normal behavior of skipClient
  • if you use skipClient, you won't have any front generated
  • in this use case, there are some relationships between entities with client and entities without client
  • it means for the front part, we need generate model + service : but we don't want the front part as there is a skipClient

So if I understand well, we should do a new option: --skipClientButGenerateModelAndService :-D

I think it's faster to generate everything (without skipping client), and then:

  • delete html part
  • delete components part
  • delete route
  • delete item in menu

skipClient and skipServer are for very advanced use cases. It can't work out of the box, you need to modify the generated code.

@mshima
Copy link
Member

mshima commented Dec 19, 2020

I’m in favor of supporting single sided relationships.
Back reference would not be written and models would be independent.

@mshima
Copy link
Member

mshima commented Dec 19, 2020

@DanielFran can you confirm if manually removing Notice relationship from .jhipster/Drug.json and Symptom relationship from .jhipster/ToxicityRate.json it generates the application you want?

@DanielFran
Copy link
Member Author

@pascalgrimaud There is in fact 2 possibilities:

  • generate front model and service in front-end
  • do not generate model and service, so it cannot appears in the relationship the detail for model skipped.

What ever solution chosen, both backend and front-end should build.

@mshima In my case I wan't to include in front-end a list of notices in drug page detail.

@pascalgrimaud
Copy link
Member

What ever solution chosen, both backend and front-end should build.

Not sure about that. When using skipClient + skipServer, it's not supposed to work out of the box. You always need to do some work after generating that.
The proof is: we don't have the CI to test this part, as skipClient + skipServer are only for very advanced uses, so the end-user knows what he/she's doing.

But we can discuss about it of course :)

@github-actions
Copy link
Contributor

This issue is stale because it has been open 30 days with no activity.
Our core developers tend to be more verbose on denying. If there is no negative comment, possibly this feature will be accepted.
We are accepting PRs 😃.
Comment or this will be closed in 7 days

@egvimo
Copy link
Contributor

egvimo commented Jan 26, 2021

I have the same issue. I've created a simple example to reproduce it.

Here is the JDL:

application {
    config {
        baseName sample
        packageName sample
        applicationType monolith
        authenticationType oauth2
        buildTool gradle
        clientFramework angularX
        prodDatabaseType postgresql
        devDatabaseType postgresql
    }
    entities *
}

entity Abc {
    name String unique required
}

@skipClient
entity Xyz {
    name String unique required
}

relationship OneToMany {
    Abc{children} to Xyz{parent}
}

The generated Code with the error:

import { IXyz } from 'app/entities/xyz/xyz.model'; // Error

export interface IAbc {
  id?: number;
  name?: string;
  children?: IXyz[] | null; // Error
}

export class Abc implements IAbc {
  constructor(public id?: number, public name?: string, public children?: IXyz[] | null) {}
}

Is it possible to fix this?

@mshima
Copy link
Member

mshima commented Jan 26, 2021

Is it possible to fix this?

  • Edit .jhipster/Abc.json and remove relationship with Xyz`.
  • Regenerate with jhipster --with-entities.

@egvimo
Copy link
Contributor

egvimo commented Jan 27, 2021

This doesn't work. The generator overwrites the json files and regenerates the faulty model files.

@github-actions
Copy link
Contributor

This issue is stale because it has been open 30 days with no activity.
Our core developers tend to be more verbose on denying. If there is no negative comment, possibly this feature will be accepted.
We are accepting PRs 😃.
Comment or this will be closed in 7 days

@egvimo
Copy link
Contributor

egvimo commented Mar 2, 2021

This is issue is still relevant to me.

@MathieuAA
Copy link
Member

MathieuAA commented Mar 25, 2021

Frankly if the PR #14461 is for this issue, I'm against it. cc @mshima for the same reasons @pascalgrimaud explained.


edit: I see it still has the "needs-discussion" label too.

@mshima
Copy link
Member

mshima commented Mar 25, 2021

@MathieuAA I didn't implemented to fix this issue, but for:

  1. Reduce generated code.
  2. If a back-reference will not be used, it useless increases complexity of the application and is more error prone.
    Quoting @gzsombor at "relationship name is not synchronized" is broken #13885:
If I add a Node{mainOther} to OtherEntity{reverseMains} - then it will generate the entities, however, that will add a Set<Node> reverseMains to OtherEntity, which I would like to avoid, as doesn't make too much sense, and could accidentally trigger unwanted db queries, etc
  1. Avoids unnecessary conflicts like:
entity A {}
entity B {}
relationship ManyToOne {
  A{firstB} to B // back-reference called a
  A{secondB} to B // back-reference called a
}

I would implement a blueprint to remove back references for personal use but there is no way to differ autogenerated back references.

@mshima
Copy link
Member

mshima commented Mar 25, 2021

And according to the documentation https://www.jhipster.tech/managing-relationships/ unidirectional ARE supported.

https://www.jhipster.tech/managing-relationships/#a-unidirectional-many-to-one-relationship
https://www.jhipster.tech/managing-relationships/#a-unidirectional-one-to-one-relationship

So IMO this should be provided by default, not only optional like the PR implements.

@MathieuAA
Copy link
Member

Avoids unnecessary conflicts like:

It can easily be done at JDL level.

I agree unidirectional rels are supported, I'm not saying the opposite :) do keep in mind that I very probably wrote the doc you're referencing ;)
The main reasons unidirectional relationships are supported is because there are many use cases where it's the right way to model relationships. The same goes for bidirectional ones BTW.
The last time I checked there still were cases where unidirectional rels weren't supported because of issues regarding hibernate (I may be wrong though).

Here, I just don't see how implementing it would solve this issue's issue. I may need to read it all over again.

@mshima
Copy link
Member

mshima commented Mar 26, 2021

Here, I just don't see how implementing it would solve this issue's issue. I may need to read it all over again.

It doesn't actually fixes the this issue, but adds a way to workaround it by changing from:

relationship OneToMany {
  Drug{notice(description)} to Notice{drug(name) required},
  Symptom{toxicityRate(name)} to ToxicityRate{symptom(name)}
}

skipClient Notice, ToxicityRate

to:

relationship ManyToOne {
  Notice{drug(name) required} to Drug
  ToxicityRate{symptom(name)} to Symptom
}

skipClient Notice, ToxicityRate
  • At jhipster 6 we had flatten relationships, so Drug had the fields from Notice in its model.
  • At jhipster 7 Drug imports Notice model, with skipClient Notice Notice model is not generated 💥 .
  • By dropping Drug to Notice back reference, Drug will stop importing Notice model and the build will succeed.

A fix would be to skip the relationship if the otherEntity is @SkipClient.
But IMO frontend models should match backend models.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants