generator-jhipster icon indicating copy to clipboard operation
generator-jhipster copied to clipboard

JHipster mvnw verify fails due to an infinite loop (due to circular relationships) in the test generated entity code.

Open naris opened this issue 3 years ago • 0 comments

Overview of the issue

I have a project with entities with relationships that refer to each other. There is an UPC Entity with a ManyToOne relationship with a Platform entity with a ManytoOne relationship to a Category entity.

The generated test code has a CategoryResourceIT class with this getAllCategoriesByPlatformIsEqualToSomething() method:

    @Test
    @Transactional
    void getAllCategoriesByPlatformIsEqualToSomething() throws Exception {
        // Initialize the database
        categoryRepository.saveAndFlush(category);
        Platform platform;
        if (TestUtil.findAll(em, Platform.class).isEmpty()) {
            platform = PlatformResourceIT.createEntity(em);
            em.persist(platform);
            em.flush();
        } else {
            platform = TestUtil.findAll(em, Platform.class).get(0);
        }
        em.persist(platform);
        em.flush();
        category.addPlatform(platform);
        categoryRepository.saveAndFlush(category);
        Long platformId = platform.getId();

        // Get all the categoryList where platform equals to platformId
        defaultCategoryShouldBeFound("platformId.equals=" + platformId);

        // Get all the categoryList where platform equals to (platformId + 1)
        defaultCategoryShouldNotBeFound("platformId.equals=" + (platformId + 1));
    }

which has a call to platform = PlatformResourceIT.createEntity(em) which is here:

    /**
     * Create an entity for this test.
     *
     * This is a static method, as tests for other entities might also need it,
     * if they test an entity which requires the current entity.
     */
    public static Platform createEntity(EntityManager em) {
        Platform platform = new Platform()
            .primarySymbol(DEFAULT_PRIMARY_SYMBOL)
            .fieldName(DEFAULT_FIELD_NAME)
            .fieldDescription(DEFAULT_FIELD_DESCRIPTION)
            .fieldLength(DEFAULT_FIELD_LENGTH)
            .fieldValue(DEFAULT_FIELD_VALUE)
            .inUse(DEFAULT_IN_USE)
            .premiumField(DEFAULT_PREMIUM_FIELD)
            .approvalRequired(DEFAULT_APPROVAL_REQUIRED)
            .token(DEFAULT_TOKEN)
            .sasKey(DEFAULT_SAS_KEY)
            .rateId(DEFAULT_RATE_ID)
            .countType(DEFAULT_COUNT_TYPE)
            .caseable(DEFAULT_CASEABLE)
            .sanRequired(DEFAULT_SAN_REQUIRED)
            .waiverRequired(DEFAULT_WAIVER_REQUIRED)
            .createUser(DEFAULT_CREATE_USER)
            .createDate(DEFAULT_CREATE_DATE)
            .modifyUser(DEFAULT_MODIFY_USER)
            .modifyDate(DEFAULT_MODIFY_DATE);
        // Add required entity
        FieldValue fieldValue;
        if (TestUtil.findAll(em, FieldValue.class).isEmpty()) {
            fieldValue = FieldValueResourceIT.createEntity(em);
            em.persist(fieldValue);
            em.flush();
        } else {
            fieldValue = TestUtil.findAll(em, FieldValue.class).get(0);
        }
        platform.getValues().add(fieldValue);
        // Add required entity
        UPC uPC;
        if (TestUtil.findAll(em, UPC.class).isEmpty()) {
            uPC = UPCResourceIT.createEntity(em);
            em.persist(uPC);
            em.flush();
        } else {
            uPC = TestUtil.findAll(em, UPC.class).get(0);
        }
        platform.setUpc(uPC);
        return platform;
    }

Which calls UPCResourceIT.createEntity(em) which had already been called and starts a infinite loop or circular references that continues until there is a stack overflow :(

    /**
     * Create an entity for this test.
     *
     * This is a static method, as tests for other entities might also need it,
     * if they test an entity which requires the current entity.
     */
    public static UPC createEntity(EntityManager em) {
        UPC uPC = new UPC()
            .upcKey(DEFAULT_UPC_KEY)
            .name(DEFAULT_NAME)
            .description(DEFAULT_DESCRIPTION)
            .dataSource(DEFAULT_DATA_SOURCE)
            .keywords(DEFAULT_KEYWORDS)
            .userNotes(DEFAULT_USER_NOTES)
            .restrictedResellerFlag(DEFAULT_RESTRICTED_RESELLER_FLAG)
            .hidden(DEFAULT_HIDDEN)
            .createUser(DEFAULT_CREATE_USER)
            .createDate(DEFAULT_CREATE_DATE)
            .modifyUser(DEFAULT_MODIFY_USER)
            .modifyDate(DEFAULT_MODIFY_DATE);
        // Add required entity
        Platform platform;
        if (TestUtil.findAll(em, Platform.class).isEmpty()) {
            platform = PlatformResourceIT.createEntity(em);
            em.persist(platform);
            em.flush();
        } else {
            platform = TestUtil.findAll(em, Platform.class).get(0);
        }
        uPC.getPlatforms().add(platform);
        // Add required entity
        Attribute attribute;
        if (TestUtil.findAll(em, Attribute.class).isEmpty()) {
            attribute = AttributeResourceIT.createEntity(em);
            em.persist(attribute);
            em.flush();
        } else {
            attribute = TestUtil.findAll(em, Attribute.class).get(0);
        }
        uPC.setAttribute(attribute);
        // Add required entity
        Category category;
        if (TestUtil.findAll(em, Category.class).isEmpty()) {
            category = CategoryResourceIT.createEntity(em);
            em.persist(category);
            em.flush();
        } else {
            category = TestUtil.findAll(em, Category.class).get(0);
        }
        uPC.setCategory(category);
        return uPC;
    }
Motivation for or Use Case

Running ./mvnw verify on a newly generated project, with no changes whosoever, should not ever fail.

Reproduce the error

Generate a jhipster project. Generate entities with the JDL shown below. run ./mvnw verify

Related issues

https://github.com/jhipster/generator-jhipster/issues/19800

Suggest a Fix

I am still researching this issue, I have do not have a fix at this time.

JHipster Version(s)

7.8.1, but this applies to all versions of jhipster.

JHipster configuration

JDL definitions
@filter
@paginate(pagination)
entity UPC {
    upcKey String maxlength(15)
    name String maxlength(250) required
    description String maxlength(1024)
    dataSource TextBlob
    keywords TextBlob
    userNotes TextBlob
    restrictedResellerFlag Boolean
    hidden Boolean
    createUser String required
    createDate Date required
    modifyUser String
    modifyDate Date
}

@filter @paginate(pagination) entity UPCRule { ruleText TextBlob required ruleDate Date required createUser String createDate Date modifyUser String modifyDate Date }

@filter @paginate(pagination) entity PrivateNotes { noteText TextBlob required noteDate Date required createUser String createDate Date modifyUser String modifyDate Date }

@filter @paginate(pagination) entity PlatformType { name String maxlength(10) required description String }

@filter @paginate(pagination) entity Platform { primarySymbol String maxlength(128) required fieldName String maxlength(250) required fieldDescription String maxlength(1024) fieldLength Integer fieldValue String maxlength(100) inUse Boolean premiumField Boolean approvalRequired Boolean token String maxlength(50) sasKey String maxlength(10) rateId String maxlength(10) countType String maxlength(1) caseable Boolean sanRequired Boolean waiverRequired Boolean createUser String createDate Date modifyUser String modifyDate Date }

@filter @paginate(pagination) entity PlatformDE { ecapsKey Integer defaultValue String maxlength(10) usedInBilling Boolean displayZeroCounts Boolean areaFillinRequired Boolean omniKvp String maxlength(30) createUser String createDate Date modifyUser String modifyDate Date }

@filter @paginate(pagination) entity PlatformInst { pricingFlag Boolean selectFlag Boolean outputFlag Boolean crosstabFlag Boolean omniKvp String maxlength(30) createUser String createDate Date modifyUser String modifyDate Date }

@filter @paginate(pagination) entity PlatformList { pricingFlag Boolean selectFlag Boolean outputFlag Boolean crosstabFlag Boolean createUser String createDate Date modifyUser String modifyDate Date }

@filter @paginate(pagination) entity Product { name String description String productKey Integer min(0) max(999) createUser String createDate Date modifyUser String modifyDate Date }

@filter @paginate(pagination) entity Release { version String releaseDate Date }

@filter @paginate(pagination) entity Dimension { name String maxlength(128) required description String createUser String required createDate Date required modifyUser String modifyDate Date }

@filter @paginate(pagination) entity Category { name String maxlength(128) required createUser String required createDate Date required modifyUser String modifyDate Date }

@filter @paginate(pagination) entity Universe { code String maxlength(10) required name String maxlength(128) required }

@filter @paginate(pagination) entity Attribute { fieldLevel String maxlength(128) createUser String required createDate Date required modifyUser String modifyDate Date }

@filter @paginate(pagination) entity Section { sectionKey String maxlength(10) required name String maxlength(128) required selfReported Boolean modeled Boolean thirdParty Boolean areaLevel Boolean compiled Boolean updatedDaily Boolean updatedWeekly Boolean updatedBiWeeekly Boolean updatedMonthly Boolean updatedSixWeeeks Boolean updatedQuatrerly Boolean updatedSemiAnnually Boolean createUser String createDate Date modifyUser String modifyDate Date }

@filter @paginate(pagination) entity FieldValue { fieldValue String maxlength(25) required valueDefinition String averageMatchRate Float min(0) max(100) displayOrder Integer activeFlag Boolean createUser String createDate Date modifyUser String modifyDate Date }

@filter @paginate(pagination) entity Task { name String required taskUser String maxlength(25) required taskOrder Integer showOnMainPage Boolean createUser String createDate Date modifyUser String modifyDate Date }

@filter @paginate(pagination) entity Step { completed Boolean notes TextBlob createUser String createDate Date modifyUser String modifyDate Date }

@filter @paginate(pagination) entity ProtectedClass { code Integer min(0) max(9) required name String maxlength(128) description String maxlength(1024) }

@filter @paginate(pagination) entity Derivation { code String maxlength(10) required name String maxlength(128) description String maxlength(1024) }

@filter @paginate(pagination) entity SourceType { code String maxlength(10) required name String maxlength(128) description String maxlength(1024) }

@filter @paginate(pagination) entity EpsilonDataSource { name String maxlength(128) }

relationship OneToOne { PlatformDE{platform} to Platform{de} PlatformInst{platform} to Platform{install} PlatformList{platform} to Platform{list} }

relationship ManyToOne { UPC{attribute required} to Attribute UPC{category required} to Category UPC{protectedClass} to ProtectedClass UPC{epsilonDataSource} to EpsilonDataSource PlatformDE{section} to Section Platform{release} to Release Platform{category} to Category{platform} Platform{platformType} to PlatformType Product{platformType} to PlatformType Dimension{universe} to Universe Step{task} to Task }

relationship OneToMany { UPC{rules} to UPCRule{upc required} UPC{privateNotes} to PrivateNotes{upc required} UPC{platforms required} to Platform{upc required} Platform{values required} to FieldValue Dimension{categories required} to Category UPC{steps} to Step }

relationship ManyToMany { UPC{sourceType} to SourceType{upc} Platform{product} to Product{platform} Platform{derivation} to Derivation{platform} }

Entity configuration(s) entityName.json files generated in the .jhipster directory
Browsers and Operating System

Windows, Edge

  • [X] Checking this box is mandatory (this is just to show you read everything)

naris avatar Sep 21 '22 20:09 naris