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

adjusts for embedded entities #25976

Merged
merged 7 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 16 additions & 13 deletions .github/workflows/linked-issue-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,38 +59,41 @@ jobs:
uses: actions/checkout@v4
with:
path: generator-jhipster
fetch-depth: 1
- name: 'SETUP: environment'
id: setup
uses: ./generator-jhipster/.github/actions/setup
fetch-depth: 2
- uses: ./generator-jhipster/.github/actions/setup-default-node-java
- uses: jhipster/actions/setup-runner@v0
with:
maven-cache: true
gradle-cache: true
binary-dir: ${{ github.workspace }}/generator-jhipster/bin
#----------------------------------------------------------------------
# Install JHipster and generate project+entities
#----------------------------------------------------------------------
- name: 'GENERATION: install JHipster'
run: $JHI_SCRIPTS/10-install-jhipster.sh
- run: npm ci --ignore-scripts
working-directory: ${{ github.workspace }}/generator-jhipster
- name: 'GENERATION: project'
id: project
run: jhipster from-issue "${{ matrix.linked-issue }}" --no-code-workspace --disable-blueprints
- name: 'GENERATION: jhipster info'
run: jhipster.cjs from-issue "${{ matrix.linked-issue }}" --no-code-workspace --disable-blueprints
env:
# generate-sample uses JHI_FOLDER_APP to generate the application.
JHI_FOLDER_APP: ${{ github.workspace }}/app
- run: jhipster.cjs info
if: steps.project.outputs.contains-sample != 'false'
run: $JHI_SCRIPTS/14-jhipster-info.sh
#----------------------------------------------------------------------
# Launch tests
#----------------------------------------------------------------------
- name: 'PREPARE: npm install'
if: steps.project.outputs.contains-sample != 'false'
run: npm install
timeout-minutes: 7
- uses: jhipster/actions/build-jhipster-bom@v0
with:
jhipster-bom-ref: main
- name: 'TESTS: backend'
if: steps.project.outputs.contains-sample != 'false'
id: backend
run: npm run ci:backend:test --if-present
timeout-minutes: 15
- name: 'PREPARE: npm install'
if: steps.project.outputs.contains-sample != 'false'
run: npm install
timeout-minutes: 7
- name: 'TESTS: frontend'
if: steps.project.outputs.contains-sample != 'false'
id: frontend
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
<%_
const tsKeyId = this.generateTestEntityId(primaryKey.type);
const allRelationshipsByEntityNeedingOptions = Object
.values(differentRelationships)
.map(relationships => relationships.filter(rel => rel.persistableRelationship))
.values(relationshipsByOtherEntity)
.map(relationships => relationships.filter(rel => rel.persistableRelationship && !rel.otherEntity.embedded))
.filter(relationships => relationships.length > 0);
const testEntityPrimaryKey0 = this.generateTestEntityPrimaryKey(primaryKey, 0);
const testEntityPrimaryKey1 = this.generateTestEntityPrimaryKey(primaryKey, 1);
Expand Down Expand Up @@ -245,7 +245,7 @@ describe('<%= entityAngularName %> Management Update Component', () => {
<%_ } _%>
});

<%_ const trackedRelationships = Object.values(differentRelationships).filter(arr => arr.some(rel => rel.persistableRelationship && rel.otherEntity.primaryKey));
<%_ const trackedRelationships = Object.values(relationshipsByOtherEntity).filter(arr => arr.some(rel => rel.persistableRelationship && !rel.otherEntity.embedded));
if (trackedRelationships.length > 0) {
_%>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
-%>
<%_
const allRelationshipsByEntityNeedingOptions = Object
.values(differentRelationships)
.map(relationships => relationships.filter(rel => rel.persistableRelationship))
.values(relationshipsByOtherEntity)
.map(relationships => relationships.filter(rel => rel.persistableRelationship && !rel.otherEntity.embedded))
.filter(relationships => relationships.length > 0);
_%>
import { Component, inject, OnInit<% if (anyFieldHasImageContentType) { %>, ElementRef<% } %> } from '@angular/core';
Expand All @@ -39,18 +39,15 @@ import { AlertError } from 'app/shared/alert/alert-error.model';
import { EventManager, EventWithContent } from 'app/core/util/event-manager.service';
import { DataUtils, FileLoadError } from 'app/core/util/data-util.service';
<%_ } _%>
<%_
Object.keys(differentRelationships).forEach(key => {
if (differentRelationships[key].some(rel => rel.persistableRelationship)) {
const uniqueRel = differentRelationships[key][0];
<%_ for (const relationshipsByEntityNeedingOptions of allRelationshipsByEntityNeedingOptions) {
const uniqueRel = relationshipsByEntityNeedingOptions[0];
if (uniqueRel.otherEntityAngularName !== entityAngularName) {
_%>
import { I<%= uniqueRel.otherEntityAngularName %> } from 'app/entities/<%= uniqueRel.otherEntityPath %>/<%= uniqueRel.otherEntityFileName %>.model';
import { <%= uniqueRel.otherEntityAngularName %>Service } from 'app/entities/<%= uniqueRel.otherEntityPath %>/service/<%= uniqueRel.otherEntityFileName %>.service';
<%_
}
}
});
_%>
<%_ const enumImports = this.generateEntityClientEnumImports(fields); _%>
<%_ enumImports.forEach( (importedPath, importedType) => { _%>
Expand All @@ -70,7 +67,7 @@ export class <%= entityAngularName %>UpdateComponent implements OnInit {
<%- this._.lowerFirst(importedType) %>Values = Object.keys(<%- importedType %>);
<%_ }); _%>

<%_ for (const relationshipsByEntityNeedingOptions of Object.values(differentRelationships).map(relationships => relationships.filter(rel => rel.persistableRelationship)).filter(relationships => relationships.length > 0)) { _%>
<%_ for (const relationshipsByEntityNeedingOptions of allRelationshipsByEntityNeedingOptions) { _%>
<%_ const relationshipsWithCustomUniqueOptions = relationshipsByEntityNeedingOptions.filter(rel => rel.relationshipOneToOne && rel.otherRelationship); _%>
<%_ if (relationshipsByEntityNeedingOptions.length > relationshipsWithCustomUniqueOptions.length) { _%>
<%_ const otherEntity = relationshipsByEntityNeedingOptions[0].otherEntity _%>
Expand All @@ -87,17 +84,14 @@ export class <%= entityAngularName %>UpdateComponent implements OnInit {
<%_ } _%>
protected <%= entityInstance %>Service = inject(<%= entityAngularName %>Service);
protected <%= entityInstance %>FormService = inject(<%= entityAngularName %>FormService);
<%_
Object.keys(differentRelationships).forEach(key => {
if (differentRelationships[key].some(rel => rel.persistableRelationship)) {
const uniqueRel = differentRelationships[key][0];
<%_ for (const relationshipsByEntityNeedingOptions of allRelationshipsByEntityNeedingOptions) {
const uniqueRel = relationshipsByEntityNeedingOptions[0];
if (uniqueRel.otherEntityAngularName !== entityAngularName) {
_%>
protected <%= uniqueRel.otherEntity.entityInstance %>Service = inject(<%= uniqueRel.otherEntityAngularName %>Service);
<%_
}
}
});
_%>
<%_ if (anyFieldHasImageContentType) { _%>
protected elementRef = inject(ElementRef);
Expand All @@ -107,8 +101,8 @@ _%>
// eslint-disable-next-line @typescript-eslint/member-ordering
editForm: <%= entityAngularName %>FormGroup = this.<%= entityInstance %>FormService.create<%= entityAngularName %>FormGroup();

<%_ for (const relationshipsByEntity of Object.values(differentRelationships).filter(arr => arr.some(rel => rel.persistableRelationship && rel.otherEntity.primaryKey))) {
const { otherEntity } = relationshipsByEntity[0];
<%_ for (const relationshipsByEntityNeedingOptions of allRelationshipsByEntityNeedingOptions) {
const { otherEntity } = relationshipsByEntityNeedingOptions[0];
_%>

compare<%= otherEntity.entityAngularName %> = (o1: I<%= otherEntity.entityAngularName %> | null, o2: I<%= otherEntity.entityAngularName %> | null): boolean =>
Expand All @@ -122,7 +116,7 @@ _%>
this.updateForm(<%= entityInstance %>);
}

<%_ if (relationships.filter(rel => rel.persistableRelationship && !rel.otherEntityIsEmbedded).length > 0) { _%>
<%_ if (relationships.filter(rel => rel.persistableRelationship && !rel.otherEntity.embedded).length > 0) { _%>
this.loadRelationshipsOptions();
<%_ } _%>
});
Expand Down Expand Up @@ -225,7 +219,7 @@ _%>

<%_ if (relationships.filter(rel => rel.persistableRelationship && !rel.otherEntityIsEmbedded).length > 0) { _%>
protected loadRelationshipsOptions(): void {
<%_ for (const relationshipsByEntityNeedingOptions of Object.values(differentRelationships).map(relationships => relationships.filter(rel => rel.persistableRelationship)).filter(relationships => relationships.length > 0)) { _%>
<%_ for (const relationshipsByEntityNeedingOptions of allRelationshipsByEntityNeedingOptions) { _%>
<%_ const relationshipsWithCustomUniqueOptions = relationshipsByEntityNeedingOptions.filter(rel => rel.relationshipOneToOne && rel.otherRelationship); %>
<%_ const relationshipsWithCustomSharedOptions = relationshipsByEntityNeedingOptions.filter(rel => !relationshipsWithCustomUniqueOptions.includes(rel)); %>
<%_ const { otherEntity } = relationshipsByEntityNeedingOptions[0] _%>
Expand Down
7 changes: 4 additions & 3 deletions generators/base-application/support/prepare-relationship.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,10 @@ export default function prepareRelationship(entityWithConfig, relationship, gene

// let ownerSide true when type is 'many-to-one' for convenience.
// means that this side should control the reference.
ownerSide: relationshipManyToOne || (relationshipLeftSide && !relationshipOneToMany),
ownerSide: relationship.otherEntity.embedded || relationshipManyToOne || (relationshipLeftSide && !relationshipOneToMany),
persistableRelationship: ({ ownerSide }) => ownerSide,
relationshipUpdateBackReference: ({ ownerSide, relationshipRightSide }) =>
entityWithConfig.databaseType === NEO4J ? relationshipRightSide : !ownerSide,
relationshipUpdateBackReference: ({ ownerSide, relationshipRightSide, otherEntity }) =>
!otherEntity.embedded && (entityWithConfig.databaseType === NEO4J ? relationshipRightSide : !ownerSide),

// DB properties
columnName: hibernateSnakeCase(relationshipName),
Expand All @@ -119,6 +119,7 @@ export default function prepareRelationship(entityWithConfig, relationship, gene
relationship.otherSideReferenceExists = true;
} else if (
!ignoreMissingRequiredRelationship &&
!relationship.otherEntity.embedded &&
!relationship.relationshipIgnoreBackReference &&
entityWithConfig.databaseType !== NEO4J &&
entityWithConfig.databaseType !== DATABASE_NO &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public class <%= persistClass %> <&- fragments.extendsSection() -&>implements Se

<%_
// An embedded entity should not reference entities that embed it, unless the other entities are also embedded
for (relationship of relationships.filter(relationship => !relationship.embedded || relationship.otherEntity.embedded || relationship.ownerSide)) {
for (relationship of relationships) {
if (typeof relationship.fieldApiDescription) { _%>
<%- relationship.relationshipJavadoc %>
<%_ if (!dtoMapstruct && relationship.relationshipyApiDescription) { _%>
Expand Down Expand Up @@ -223,10 +223,6 @@ for (relationship of relationships.filter(relationship => !relationship.embedded
<&- fragments.classAdditionalFieldsMethodsSection('\n\n') -&>
<%_
for (const relationship of relationships) {
// An embedded entity should not reference entities that embed it, unless the other entities are also embedded
if (embedded && !relationship.otherEntity.embedded && !relationship.ownerSide) {
continue;
}
_%>
<%_ if (relationship.collection) { _%>
public Set<<%= relationship.otherEntity.persistClass %>> get<%= relationship.relationshipNameCapitalizedPlural %>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public class <%= persistClass %>Asserts {
<%_ for (const field of fields.filter(field => !field.transient && field.autoGenerate)) { _%>
.satisfies(e -> assertThat(e.get<%- field.fieldInJavaBeanMethod %>()).as("check <%- field.propertyName %>").isEqualTo(actual.get<%- field.fieldInJavaBeanMethod %>()))
<%_ } _%>
<%_ for (const relationship of relationships.filter(relationship => relationship.autoGenerate && !relationship.otherEntity.builtInUser)) { _%>
<%_ for (const relationship of relationships.filter(relationship => (!embedded || relationship.otherEntity.embedded) && relationship.autoGenerate && !relationship.otherEntity.builtInUser)) { _%>
.satisfies(e -> assertThat(e.get<%- relationship.propertyJavaBeanName %>()).as("check <%- relationship.propertyName %>").isEqualTo(actual.get<%- relationship.propertyJavaBeanName %>()))
<%_ } _%>
;
Expand Down Expand Up @@ -121,10 +121,10 @@ public class <%= persistClass %>Asserts {
<%_ if (relationships.some(relationship => relationship.persistableRelationship && !relationship.id && !relationship.autoGenerate && !relationship.otherEntity.builtInUser)) { _%>
assertThat(expected)
.as("Verify <%- persistClass %> relationships")
<%_ for (const relationship of relationships.filter(relationship => relationship.persistableRelationship && !relationship.id && !relationship.autoGenerate && !relationship.otherEntity.builtInUser)) { _%>
<%_ for (const relationship of relationships.filter(relationship => (!embedded || relationship.otherEntity.embedded) && relationship.persistableRelationship && !relationship.id && !relationship.autoGenerate && !relationship.otherEntity.builtInUser)) { _%>
.satisfies(e -> assertThat(e.get<%- relationship.propertyJavaBeanName %>()).as("check <%- relationship.propertyName %>").isEqualTo(actual.get<%- relationship.propertyJavaBeanName %>()))
<%_ } _%>
;
<%_ } _%>
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class <%= persistClass %>Test {
assertThat(<%= persistInstance %>).hasSameHashCodeAs(<%= persistInstance %>1);
}
<%_ } _%>
<%_ for (const relationship of relationships.filter(relationship => !relationship.otherEntity.builtIn)) { _%>
<%_ for (const relationship of relationships.filter(rel => !rel.otherEntity.builtIn && (!embedded || (rel.otherEntity.embedded && rel.ownerSide)))) { _%>

@Test
void <%- relationship.relationshipName %>Test() throws Exception {
Expand Down
4 changes: 2 additions & 2 deletions generators/server/support/prepare-entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ export function preparePostEntityServerDerivedProperties(entity) {
.forEach(relationship => {
relationship.ignoreOtherSideProperty =
entity.databaseType !== NEO4J &&
!relationship.embedded &&
!!relationship.otherEntity &&
!entity.embedded &&
!relationship.otherEntity.embedded &&
relationship.otherEntity.relationships.length > 0;
});
entity.relationshipsContainOtherSideIgnore = entity.relationships.some(relationship => relationship.ignoreOtherSideProperty);
Expand Down
1 change: 1 addition & 0 deletions generators/server/support/relationship.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const addEntitiesOtherRelationships = (entities: JSONEntity[]): Validatio
for (const relationship of entity.relationships ?? []) {
if (
!relationship.otherRelationship &&
!relationship.otherEntity.embedded &&
(relationship.otherEntityRelationshipName ||
relationship.relationshipType === 'many-to-many' ||
// OneToOne back reference is required due to filtering
Expand Down
10 changes: 8 additions & 2 deletions test-integration/samples/.jhipster/DocumentBankAccount.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,15 @@
"relationships": [
{
"otherEntityName": "embeddedOperation",
"otherEntityRelationshipName": "documentBankAccount",
"relationshipName": "embeddedOperation",
"otherEntityRelationshipName": "documentBankAccountToOne",
"relationshipName": "manyEmbeddedOperation",
"relationshipType": "one-to-many"
},
{
"otherEntityName": "embeddedOperation",
"otherEntityRelationshipName": "documentBankAccountToMany",
"relationshipName": "oneEmbeddedOperation",
"relationshipType": "many-to-one"
}
],
"service": "serviceImpl"
Expand Down
1 change: 0 additions & 1 deletion test-integration/samples/.jhipster/EmbeddedOperation.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
{
"otherEntityField": "name",
"otherEntityName": "documentBankAccount",
"otherEntityRelationshipName": "embeddedOperation",
"relationshipName": "documentBankAccount",
"relationshipType": "many-to-one"
}
Expand Down
Loading