generator-jhipster
generator-jhipster copied to clipboard
JHipster mvnw verify fails due to an infinite loop (due to circular relationships) in the test generated entity code.
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)