jhipster / generator-jhipster

JHipster is a development platform to quickly generate, develop, & deploy modern web applications & microservice architectures.
https://www.jhipster.tech
Apache License 2.0
21.47k stars 4.02k forks source link

@MapstructExpression Mapper generation problem #19845

Closed Futureglobe closed 1 year ago

Futureglobe commented 1 year ago
Overview of the issue

To get a combined representation I use @MapstructExpression inside the .jdl file. The JDL looks like this:

image

When using @MapstructExpression the mapper is generated incorrectly resulting in the following error message:

No property named "fulldetail" exists in source parameter(s). Did you mean "validfrom"?

image

This error message was also mentioned in the following issue: https://github.com/jhipster/generator-jhipster/issues/18589 But has not been resolved as far as I can see.

I suspect that this is a generation error of the mapper. I tested this inside a completely new JHipster project.

Related issues

(https://github.com/jhipster/generator-jhipster/issues/18589)

JHipster Version(s)

7.9.3

Entity configuration(s) entityName.json files generated in the .jhipster directory
.yo-rc.json file
{
  "generator-jhipster": {
    "applicationType": "monolith",
    "authenticationType": "oauth2",
    "baseName": "dataview",
    "blueprints": [],
    "buildTool": "maven",
    "cacheProvider": "no",
    "clientFramework": "angularX",
    "clientPackageManager": "npm",
    "clientTheme": "none",
    "clientThemeVariant": "",
    "creationTimestamp": 1639736978010,
    "databaseType": "sql",
    "devDatabaseType": "mysql",
    "devServerPort": 4200,
    "dtoSuffix": "DTO",
    "enableGradleEnterprise": false,
    "enableHibernateCache": false,
    "enableSwaggerCodegen": false,
    "enableTranslation": true,
    "entities": [
      "StreamData",
      "StreamLog",
      "StreamMeta",
      "StreamRouter",
      "StreamConnectionidProtocol",
      "StreamUsecaseid",
      "StreamConnectionid",
      "StreamTechcredentialsToken",
      "StreamRouterMessagetype",
      "Streamid"
    ],
    "entitySuffix": "",
    "incrementalChangelog": true,
    "jhiPrefix": "jhi",
    "jhipsterVersion": "7.9.3",
    "jwtSecretKey": "YourJWTSecretKeyWasReplacedByThisMeaninglessTextByTheJHipsterInfoCommandForObviousSecurityReasons",
    "languages": ["de", "en"],
    "lastLiquibaseTimestamp": 1651657395000,
    "messageBroker": false,
    "nativeLanguage": "de",
    "otherModules": [],
    "packageName": "de.test.package",
    "pages": [],
    "prodDatabaseType": "mysql",
    "reactive": false,
    "rememberMeKey": "YourJWTSecretKeyWasReplacedByThisMeaninglessTextByTheJHipsterInfoCommandForObviousSecurityReasons",
    "searchEngine": "elasticsearch",
    "serverPort": "8180",
    "serverSideOptions": ["searchEngine:elasticsearch"],
    "serviceDiscoveryType": "no",
    "skipCheckLengthOfIdentifier": false,
    "skipClient": false,
    "skipFakeData": false,
    "skipUserManagement": false,
    "testFrameworks": [],
    "websocket": false,
    "withAdminUi": true
  }
}

Used JDL
entity StreamData {
   date Instant
   processname String
   tecsender String
   status String maxlength(30)
   @Id uuid UUID
   transactionid String
   metainfo String
   filename String
   contentstring TextBlob
   rube String maxlength(30)
   // jobid_id Long  // pk of Streamjobs == id
   // usecaseid_id long // pk of StreamUsecaseid == id --> id | partnername | protocol | pathurl
   // sourceusecaseid long // pk of StreamUsecaseid == id --> id | partnername | protocol | pathurl
   // routerid_id long // pk of StreamRouter --> id | info
}

entity StreamLog {
   comment String
   status String
   date Instant
   // stream_data_uuid UUID // pk of StreamData == uuid
}

entity StreamMeta {
   tecsender            String
   messagetype          String
   buyergln             String
   suppliergln          String
   receivergln          String
   documentreference    String
   documentnumber       String
   documentcode         String
   documentcount        String
   meta1                String
   meta2                String
   meta3                String
   meta4                String
   // stream_data_uuid UUID  // pk of StreamData == uuid
}

entity StreamRouter {
   active Boolean
   routertype StreamRouterType
   filemask String
   tecsender String
   tecreceiver String
   basegln String
   buyergln String
   suppliergln String
   receivergln String
   info String required
   // messagetype_id Long // pk of StreamRouterMessagetype == id --> name
   // usecaseid_id Long // pk of StreamUsecaseid == id --> id | partnername | protocol | pathurl
}

entity StreamRouterMessagetype {
   name String required maxlength(30)
   description String maxlength(30)
   info String 
}

entity StreamConnectionidProtocol {
   name String required maxlength(30) 
   description String maxlength(30)
   info String 
}

entity StreamUsecaseid {
   active Boolean
   usecasename String required
   validfrom Instant

   modifyuser String
   modifydate Instant
   createdate Instant
   information String

   @MapstructExpression("java(s.getId() )")
   fulldetail String

   // connectionid_id Long // pk of StreamConnectionid == id
}

entity StreamConnectionid {
   active Boolean
   connectionname String required
   authtype StreamConnectionidAuthType 
   user String
   authkey String 
   hosturl String
   pathurl String  
   archive Boolean
   modifyuser String
   modifydate Instant
   // jobid_id Long  // pk of Streamjobs == id
   // protocol_id Long // pk of StreamConnectionidProtocol == id
   // token_id Long // pk of StreamTechcredentialsToken == id
}

entity StreamError {
  active Boolean
  process String
  activity String
  processmsg String
  processmsgcode String
  humanmsg String
  moremsg TextBlob
  sourceusecaseid Long
  targetusecaseid Long
  createdAt Instant
  uuid UUID
}

entity StreamJobs {
  active Boolean
  jobname String
  info String
  sourceinfo String
  lastrunAt Instant
  createdAt Instant
  jobtype Long
  inprogress Boolean
  jobpattern String
  delsourceitem Boolean
}

entity StreamTechcredentialsToken {
   active Boolean
   tokenname String required
   url String
   clientid String
   clientsecret String
   authkey TextBlob
   expiresat Instant
   modifyuser String
   modifydate Instant
}

entity StreamStateserviceInbound  {
  dateinit Instant
  datesend Instant
  status String
  aux1 String
  aux2 String
  aux3 String
  inboundfileuid String
  documentuid String
  outboundpackageuid String
  stateuid String
  reprocessuid String
  clearingforstateuid String
  artifacttype String
  servicename String
  createdon Instant
  statemessagelevel String
  message String
  messagecode String
  servicestepcode String
  servicesteptype String
  servicesequencenumber String
  servicestepsequencenumber String
  serviceexecutionuid String
  previousstateuids String
  previousserviceexecutionuid String
  commitid String
  serviceversion String
  buildtimestamp Instant
  dtoouuid String
  stage String
}

entity StreamStateserviceOutbound  {
  dateinit Instant
  datesend Instant
  status String
  step String
  fileuuid String
  messagelevel String
  message String
  deliveryconfirmationid String
  deliveryconfirmationmessage String
  servicesequencenumber String
  serviceexecutionuid String
  previousserviceexecutionuid String
  dtoouuid String
  timestamp Instant
  stage String
}

enum StreamConnectionidAuthType {
   PASSWORD, SSH_KEY, OAUTH2, NONE
}

enum StreamRouterType {
   DEFAULT, TECHNICAL, PARSER
}

relationship OneToMany {
   StreamRouterMessagetype{streamRouter} to StreamRouter{messagetype(name)}

   StreamJobs{streamConnectionId} to StreamConnectionid{job(jobname)}
   StreamConnectionidProtocol{streamConnectionid} to StreamConnectionid{protocol(name)} 
   StreamTechcredentialsToken{connectionId} to StreamConnectionid{token(tokenname)}
   StreamConnectionid{useCaseId} to StreamUsecaseid{connectionid(connectionname)}
   StreamJobs{streamData} to StreamData{job(jobname)}

   StreamUsecaseid{streamDataRefOne} to StreamData{sid(fulldetail)}
   StreamUsecaseid{streamDataRefTwo} to StreamData{tid(fulldetail)}

   StreamUsecaseid{streamJobsRefOne} to StreamJobs{sid(usecasename)}
   StreamUsecaseid{streamJobsRefTwo} to StreamJobs{tid(usecasename)}

   StreamUsecaseid{streamRouter} to StreamRouter{usecaseid(usecasename)}

   StreamRouter{streamData} to StreamData{routerid(info)}
}

relationship ManyToOne {
   StreamLog{streamData} to StreamData{streamLog}
   StreamMeta{streamData} to StreamData{streamMeta}
   StreamError{streamData} to StreamData{streamError}
}

// Set pagination options
paginate all with pagination

// Use Data Transfer Objects (DTO)
dto all with mapstruct

// Set service options to all
service all with serviceImpl

// filtering support
filter all

search StreamData, StreamLog, StreamMeta with elasticsearch

// Set an angular suffix
// angularSuffix * with mySuffix
Environment and Tools

openjdk version "17.0.2" 2022-01-18 OpenJDK Runtime Environment (build 17.0.2+8-86) OpenJDK 64-Bit Server VM (build 17.0.2+8-86, mixed mode, sharing)

git version 2.34.1

node: v14.18.0

npm: 8.19.1

Docker version 20.10.11, build dea9396

docker-compose version 1.29.2, build 5becea4c

Browsers and Operating System

MacOS Monterey 12.5

OmarHawk commented 1 year ago

We also have the same problem in our project.

@mshima / @DanielFran is the PR alright, or is there anything I can do to get this merged?

mshima commented 1 year ago

@OmarHawk thanks for the information, I've added a test case to the sample so we can see the changes to the generated code. Let me know if the samples is incorrect. Once CI passes we can merge it.

OmarHawk commented 1 year ago

Yes, that's a proper sample. When the mapstruct expression field is referenced as "label" for the relationship, jhipster does generate an application, but it fails to finally compile the java code. :-)

mshima commented 1 year ago

The PR doesn't change anything for the added sample: https://github.com/jhipster/generator-jhipster/actions/runs/3439427487/jobs/5738658441