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

Compile error with MongoDB & required relationships #9820

Closed
1 task done
hdurix opened this issue May 29, 2019 · 10 comments
Closed
1 task done

Compile error with MongoDB & required relationships #9820

hdurix opened this issue May 29, 2019 · 10 comments

Comments

@hdurix
Copy link
Member

hdurix commented May 29, 2019

Overview of the issue

When using MongoDB as database and entities with required relationships between them, some Integration Tests don't compile.

Motivation for or Use Case

It's clearly a bug as it does not compile :)

Reproduce the error

Generate an app with MongoDB and required relationships (see JDL below)

Related issues

Issue: #9666
PR: #9669

ping @Gabrui

Suggest a Fix

The problem is that we use TestUtil.findAll(em, ...) here in every case (MongoDB included) but this method is only defined when using sql database: see this condition.

I tried to fix it but it's a bit tricky, what I had in mind:

  • use other relationship entity repository instead of the newly created TestUtil.findAll(em, ...) method

I only mentioned MongoDB here, but I'm sure it's the same for Couchbase and Cassandra.

NB: maybe this configuration is missing in CI tests: MongoDB + required relationship.

JHipster Version(s)

JHipster from master (6.0.1)

4@0.0.0 /home/hippolyte/workspace/jhipster/samples/mongoRequired
└── (empty)

JHipster configuration, a .yo-rc.json file generated in the root folder
.yo-rc.json file
{
  "generator-jhipster": {
    "promptValues": {
      "packageName": "com.mycompany.myapp",
      "nativeLanguage": "en"
    },
    "jhipsterVersion": "6.0.1",
    "applicationType": "monolith",
    "baseName": "4",
    "packageName": "com.mycompany.myapp",
    "packageFolder": "com/mycompany/myapp",
    "serverPort": "8080",
    "authenticationType": "jwt",
    "cacheProvider": "no",
    "enableHibernateCache": false,
    "websocket": false,
    "databaseType": "mongodb",
    "devDatabaseType": "mongodb",
    "prodDatabaseType": "mongodb",
    "searchEngine": false,
    "messageBroker": false,
    "serviceDiscoveryType": false,
    "buildTool": "maven",
    "enableSwaggerCodegen": false,
    "jwtSecretKey": "bXktc2VjcmV0LXRva2VuLXRvLWNoYW5nZS1pbi1wcm9kdWN0aW9uLWFuZC10by1rZWVwLWluLWEtc2VjdXJlLXBsYWNl",
    "useSass": true,
    "clientPackageManager": "npm",
    "clientFramework": "angularX",
    "clientTheme": "none",
    "clientThemeVariant": "",
    "testFrameworks": [],
    "jhiPrefix": "jhi",
    "entitySuffix": "",
    "dtoSuffix": "DTO",
    "otherModules": [],
    "enableTranslation": true,
    "nativeLanguage": "en",
    "languages": ["en"]
  }
}
JDL for the Entity configuration(s) entityName.json files generated in the .jhipster directory
JDL entity definitions
entity Store {
  name String
}
entity Rule
relationship OneToMany {
  Store{rule} to Rule{store(name) required}
}


Environment and Tools

openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-8u212-b03-0ubuntu1.18.04.1-b03)
OpenJDK 64-Bit Server VM (build 25.212-b03, mixed mode)

git version 2.17.1

node: v10.15.3

npm: 6.4.1

yeoman: 2.0.2

yarn: 1.6.0

Docker version 18.06.3-ce, build d7080c1

docker-compose version 1.21.1, build 5a3f1a3

JHipster configuration
Entity configuration(s) entityName.json files generated in the .jhipster directory
Entity Rule definition
{
    "name": "Rule",
    "fields": [],
    "relationships": [
        {
            "relationshipType": "many-to-one",
            "otherEntityName": "store",
            "otherEntityRelationshipName": "rule",
            "relationshipValidateRules": "required",
            "relationshipName": "store",
            "otherEntityField": "name"
        }
    ],
    "changelogDate": "20190529133335",
    "entityTableName": "rule",
    "dto": "no",
    "pagination": "no",
    "service": "no",
    "jpaMetamodelFiltering": false,
    "fluentMethods": true,
    "clientRootFolder": "",
    "applications": "*"
}
Entity Store definition
{
    "name": "Store",
    "fields": [
        {
            "fieldName": "name",
            "fieldType": "String"
        }
    ],
    "relationships": [
        {
            "relationshipType": "one-to-many",
            "otherEntityName": "rule",
            "otherEntityRelationshipName": "store",
            "relationshipName": "rule"
        }
    ],
    "changelogDate": "20190529133334",
    "entityTableName": "store",
    "dto": "no",
    "pagination": "no",
    "service": "no",
    "jpaMetamodelFiltering": false,
    "fluentMethods": true,
    "clientRootFolder": "",
    "applications": "*"
}
Browsers and Operating System
  • Checking this box is mandatory (this is just to show you read everything)
@Gabrui
Copy link
Contributor

Gabrui commented May 29, 2019

Are unique constraints enforced in mongodb? If not, we could just force my fix to the sql case. Just changing this line

<%_ if (otherEntityName === 'user') { // TODO or other entity has no unique fields _%>

to

<%_ if (otherEntityName === 'user' || databaseType !== 'sql') { // TODO or other entity has no unique fields _%>

would resolve.

But I really don't know how those other database types work.

@hdurix
Copy link
Member Author

hdurix commented May 29, 2019

It's compiling but some tests are failing, I guess that's because we don't create the associated relationships entities during the tests, but I don't know how MongoDB relationships are working either.

I used the same JDL as you @Gabrui:

JDL with required definitions
entity BankAccount {
  name String required
  bankNumber Integer
  agencyNumber Long
  lastOperationDuration Float
  meanOperationDuration Double
  balance BigDecimal required
  openingDay LocalDate
  lastOperationDate Instant
  active Boolean
  accountType BankAccountType
  attachment AnyBlob
  description TextBlob
}
entity TheLabel {
  labelName String required minlength(3)
}
entity Operation {
  date Instant required
  description String
  amount BigDecimal required
}

enum BankAccountType {
  CHECKING,
  SAVINGS,
  LOAN
}

entity Department {
  name String required,
  description TextBlob,
  advertisement Blob,
  logo ImageBlob
}

/**
 * JobHistory comment.
 */
entity JobHistory {
  startDate ZonedDateTime,
  endDate ZonedDateTime,
  language Language
}

enum Language {
  FRENCH, ENGLISH, SPANISH
}

enum JobType {
  BOSS, SLAVE
}

entity Job {
  title String minlength(5) maxlength(25),
  type JobType,
  minSalary Long,
  maxSalary Long
}

/**
 * The Employee entity.
 * Second line in javadoc.
 */
entity Employee {
  /**
   * The firstname attribute.
   */
  firstName String,
  lastName String,
  email String,
  phoneNumber String,
  hireDate ZonedDateTime,
  salary Long,
  commissionPct Long
}

entity Location {
  streetAddress String,
  postalCode String,
  city String,
  stateProvince String
}

entity Task {
  title String,
  description String
}

entity GoldenBadge {
  name String
}

entity SilverBadge {
  name String
}

entity Identifier {
  name String required unique
}

entity Country {
  name String
}

entity Region {
  name String
}

relationship OneToOne {
  Department{location} to Location,
  Employee{user(login)} to User with jpaDerivedIdentifier
}

relationship OneToMany {
  BankAccount{operation} to Operation{bankAccount(name)}
}
relationship ManyToOne {
  BankAccount{user(login)} to User
}
relationship ManyToMany {
  Operation{theLabel(labelName)} to TheLabel{operation}
}

relationship OneToMany {
  /**
   * A relationship
   */
  Department{employee} to
  /**
   * Another side of the same relationship,
   */
  Employee{department},
  Employee{job} to Job{emp(lastName)},
  Location{country} to Country,
  Country{area(name)} to Region
}

relationship ManyToOne {
  Employee{manager(lastName)} to Employee,
  Employee{sibag(name) required} to SilverBadge,
  Employee{gobag(name) required} to GoldenBadge,
  SilverBadge{iden(name) required} to Identifier,
  GoldenBadge{iden(name) required} to Identifier
}

relationship ManyToMany {
  JobHistory to Department,
  JobHistory to Job{history},
  JobHistory{emp(firstName)} to Employee{history},
  Job{chore(title)} to Task{linkedJob(title)}
}


angularSuffix BankAccount with mySuffix
filter BankAccount, Employee
clientRootFolder BankAccount, TheLabel, Operation with test-root

paginate TheLabel, Job with pagination
paginate Operation, JobHistory, Employee with infinite-scroll

service TheLabel, Employee, Department, Region with serviceClass
service BankAccount, Location, Country with serviceImpl

@ivangsa if you have got an idea.

@Gabrui
Copy link
Contributor

Gabrui commented May 29, 2019

Then we need a way to make a query in those other databases. I remember that the first time I tried to fix that bug I imported the entitie's Repository but I also ran into the problem of the persistence context (it needed the @transactional decorator to work) but it also gave other problems so I used the 'em' to make the query and simplify.

@ivangsa
Copy link
Contributor

ivangsa commented May 30, 2019

Hi, I will look into it..
There is also a compilation problem in services related to the primary key not being an string...
#9826

@hdurix
Copy link
Member Author

hdurix commented May 30, 2019

Yes @Gabrui the other issue using repositories inside the createEntity method is that this method is static (in order to be called from other integration tests) so the @Autowired repositories can't be used here.

@ivangsa thanks! I also noticed this compilation problem with ids using services (with the last JDL I gave).

@ivangsa
Copy link
Contributor

ivangsa commented May 30, 2019

after aplying fix proposed by @Gabrui ,
I think the remaining failing tests are because code is generated for "isUsingMapsId === true" which does not apply to mondgodb... harcoding that to false makes generated tests to pass...

@ivangsa
Copy link
Contributor

ivangsa commented May 31, 2019

hi, I think failing tests are caused by this (incompatible) setting in the jdl:
Employee{user(login)} to User with jpaDerivedIdentifier
this is generating code in services and tests for MapIds incompatible with mongodb..

@nonomoho
Copy link
Member

For me there are some changes to do in EntityResourceIT.java.ejs file:
This line:
if (TestUtil.findAll(em, <%= otherEntityNameCapitalized %>.class).isEmpty()) {
And the "else" part:

} else {
    <%= otherEntityName %> = TestUtil.findAll(em, <%= otherEntityNameCapitalized %>.class).get(0);
}

should only be used for the SQL databaseType.

I can try to push something!

@hdurix
Copy link
Member Author

hdurix commented Jun 1, 2019

@ivangsa sorry, I just copied the JDL and changed the databaseType without checking it was correct.

Both fixes are correct, the one from @nonomoho can be easier to read later.

@hdurix
Copy link
Member Author

hdurix commented Jun 1, 2019

Fixed by #9830.

@hdurix hdurix closed this as completed Jun 1, 2019
@pascalgrimaud pascalgrimaud added this to the 6.1.0 milestone Jun 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants