Let's say you have a required OneToOne relationship between a SponsorAgreement and a Sponsor. After creating a SponsorAgreement, when you edit it, you see the same Sponsor twice in the combobox.
When you create a SponsorAgreement you only have one sponsor in the combox. When you edit it, you can see the same sponsor twice.
Generate a simple monolith with the following model :
entity Sponsor {
    name String
}
entity SponsorAgreement {
    total Float
}
relationship OneToOne {
    SponsorAgreement{sponsor required} to Sponsor{sponsorAgreement}
}
.subscribe((res: ResponseWrapper) => {
    if (!this.sponsorAgreement.sponsor || !this.sponsorAgreement.sponsor.id) {
        this.sponsors = res.json;
    } else {
        this.sponsorService
            .find(this.sponsorAgreement.sponsor.id)
            .subscribe((subRes: Sponsor) => {
                this.sponsors = [subRes].concat(res.json);
            }, (subRes: ResponseWrapper) => this.onError(subRes.json));
    }
[email protected] /Users/agoncal/Documents/Code/Temp/jhipsterdouble
└── [email protected] 
{
  "generator-jhipster": {
    "promptValues": {
      "packageName": "io.bugdouble"
    },
    "jhipsterVersion": "4.11.0",
    "baseName": "bugdouble",
    "packageName": "io.bugdouble",
    "packageFolder": "io/bugdouble",
    "serverPort": "8080",
    "authenticationType": "jwt",
    "hibernateCache": "ehcache",
    "clusteredHttpSession": false,
    "websocket": false,
    "databaseType": "sql",
    "devDatabaseType": "h2Memory",
    "prodDatabaseType": "mysql",
    "searchEngine": false,
    "messageBroker": false,
    "serviceDiscoveryType": false,
    "buildTool": "maven",
    "enableSocialSignIn": false,
    "enableSwaggerCodegen": false,
    "jwtSecretKey": "replaced-by-jhipster-info",
    "clientFramework": "angularX",
    "useSass": false,
    "clientPackageManager": "yarn",
    "applicationType": "monolith",
    "testFrameworks": [],
    "jhiPrefix": "jhi",
    "enableTranslation": false
  }
}
entityName.json files generated in the .jhipster directory
JDL entity definitions
entity Sponsor (sponsor) {
  name String
}
entity SponsorAgreement (sponsor_agreement) {
  total Float
}
relationship OneToOne {
  SponsorAgreement{sponsor required} to Sponsor{sponsorAgreement}
}
java version "1.8.0_152"
Java(TM) SE Runtime Environment (build 1.8.0_152-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.152-b16, mixed mode)
git version 2.15.0
node: v8.9.0
npm: 5.5.1
After a little investigation I found out that:
this.sponsorService
        .query({filter: 'sponsoragreement-is-null'})
        .subscribe((res: ResponseWrapper) => {
            if (!this.sponsorAgreement.sponsor || !this.sponsorAgreement.sponsor.id) {
                this.sponsors = res.json;
            } else {
                this.sponsorService
                    .find(this.sponsorAgreement.sponsor.id)
                    .subscribe((subRes: Sponsor) => {
                        this.sponsors = [subRes].concat(res.json);
                    }, (subRes: ResponseWrapper) => this.onError(subRes.json));
            }You need to generate the non-owning relationship as well.
This way the 'sponsoragreement-is-null' filter will be generated server side.
It is used to have all the entities not already linked (because it's a OneToOne and it's what we want).
this following line need to be added (PR) in request-util.ts:
params.set('filter', req.filter);
@ctamisier Can you give a hint how to force jhipster cli to force creating also the non-owning relationship? I can confirm that the client is making the call with filter=sponsoragreement-is-null as parameter. The problem is that the server side, in this case _SponsorResource_, does not do anything with this filter. On the other hand in the _SponsorService_ there is a method findAllWhereSponsorAgreementIsNull. Unfortunately this method has no reference in the generated code. IMHO there are two option:
--with-entities --foce and that way the code which is using findAllWhereSponsorAgreementIsNullis gone be generated.SponsorService.findAllWhereSponsorAgreementIsNull is missing and need to be implemented.Can you give some feedback on the option to know which one to follow 😃 .
Sure!
Actually it should work after integrating the PR https://github.com/jhipster/generator-jhipster/pull/6808
I ran your JDL jhipster import-jdl jhipster-jdl.jh with the following content:
entity Sponsor {
    name String
}
entity SponsorAgreement {
    total Float
}
relationship OneToOne {
    SponsorAgreement{sponsor required} to Sponsor{sponsorAgreement}
}
and in SponsorResource I have the following method, and everything seems working for me :
    /**
     * GET  /sponsors : get all the sponsors.
     *
     * @param filter the filter of the request
     * @return the ResponseEntity with status 200 (OK) and the list of sponsors in body
     */
    @GetMapping("/sponsors")
    @Timed
    public List<Sponsor> getAllSponsors(@RequestParam(required = false) String filter) {
        if ("sponsoragreement-is-null".equals(filter)) {
            log.debug("REST request to get all Sponsors where sponsorAgreement is null");
            return StreamSupport
                .stream(sponsorRepository.findAll().spliterator(), false)
                .filter(sponsor -> sponsor.getSponsorAgreement() == null)
                .collect(Collectors.toList());
        }
        log.debug("REST request to get all Sponsors");
        return sponsorRepository.findAll();
        }
You mentioned SponsorService but I don't see it in the JDL, do you have more settings in your JDL that we could try to figure out if the problem is somewhere else.
@ctamisier Indeed with the last version of jhipster cli, i.e. which is already having the PR #6808 included, the generated app works 👍 . On the other hand if we are using filtering this is not working anymore. Here are my founding:
jhipster --with-entities --foce and not with jhipster import-jdl so that the json files in .jhipster are not override.This brings up the following questions:
SponsorService Yeah there is no http request from the front-end using the JPA Filtering mechanism for the '*-is-null' case.
So I thought this request would make the job but it doesn't work:
curl 'http://localhost:9000/api/sponsors?sponsorAgreementId.specified=false'
it actually does the same SQL request than:
curl 'http://localhost:9000/api/sponsors?id.specified=false'
which is:
Hibernate: select sponsor0_.id as id1_5_, sponsor0_.name as name2_5_ from sponsor sponsor0_ where sponsor0_.id is null (which is not what you want)
So I think I need to study more about the JPA Filtering mechanism..
I think this http request is the way to go when we have JPA filtering enable and this '*-is-null' case:
'http://localhost:9000/api/sponsors?sponsorAgreementId.specified=false'
But we are in the mappedBy side, so the sponsorAgreement field in the Sponsor entity is not the owner of the relation. That's why it's not working (I think).
So in the implementation, the specification to create should be (I tried it and it seems fine):
specified
? (root, query, builder) -> builder.isNotNull(root.join(Sponsor_.sponsorAgreement, JoinType.LEFT).get(SponsorAgreement_.id))
: (root, query, builder) -> builder.isNull(root.join(Sponsor_.sponsorAgreement, JoinType.LEFT).get(SponsorAgreement_.id)));
instead of
specified 
? (root, query, builder) -> builder.isNotNull(root.get(field))
: (root, query, builder) -> builder.isNull(root.get(field));
I am not sure that it doesn't have any impacts on the rest of JPA filtering architecture if we want to integrate it in the generator.
I really don't master this yet..
Maybe you could have this like a hack (before having a real solution) and have a specific REST service for this JPA Specification request to have this 'sponsoragreement-is-null' filter working.
@ctamisier You are a faster than me 😃 I have also narrowed down to the same query /api/sponsors?sponsorAgreementId.specified=false which should indeed return a list of all the sponsor that are not having a sponsorAgreement. If your suggestion is gone work then we need to consider that findAllWhereSponsorAgreementIsNull  in the SponsorService is gone be more or less absolute because the same can be done over filter.
I anyone working on this?
I just saw that the pull request #37 is having some conflicts. The reason for this I guess it's because the PR was created some months ago. I will try this week to create a PR based on the current master. Unfortunately I will not manage to have a look on this before weekend.
I tried to reproduce the bug and it seems that it has been fixed. Can someone confirm please ?
The issue still exist. I just update the project where it can be reproduce here. Unfortunately because of flu and Easter I was not able to update the pull request #37. Today I just start to work again and hoppe by the WE to get it done.
@duderoot I cloned your project and updated it to the 5.0 beta and it's fixed. I had delete /src/* though.
@agaspardcilia do you mean the original issue in this ticket is fixed?
@deepu105 Yes, it is.
let's close it then. @agoncal @duderoot do let us know if you see any other issue
@deepu105 unfortunately the problem is not solved and still exist also after an upgrade on version 5.0.0-beta.0. @agaspardcilia I just updated my project with the version v5.0.0-beta.0 here. One can run the project and see that the error still persist. If I have omitted something pls let me know, but in my opinion we need to reopen the issue. I have also update my project to v4.13.3 here and the problem also exist.
@duderoot could you please post a screenshot of what you see
@deepu105 of course: the problem is that the select should show only id's which don't have a sponsorAgreement i.e. 1 as the curret selected version and 2 as a second option.

I try to make a recap because the issue is getting a little to long. The app it should use _jpaMetamodelFiltering_  Using this option the frontend should make a call on the backend  over /api/sponsors?sponsorAgreementId.specified=false. At the moment the generated frontend is calling /api/sponsors?filter=sponsoragreement-is-null which is not filtering anything at all. So a first step in order to fix this bug it will be to generate the proper url when calling the backend.
Second the implementation in the server side jhipster lib need to be patch in so that the filter is working for this case. For this I have created a pull request #37 which is having some conflicts. Now I see that @jdubois and @erikkemperman are migrating the server side lib from
io.github.jhipster : jhipster to io.github.jhipster : jhipster-framework
I just create a new PR jhipster/jhipster/#59 for the server side lib jhipster-framework which I assume is gone be part of JHipster V5
I can't reproduce this using the config from the first post, it looks like it's working:
Creating a new entity:

Updating an existing entity:

Thanks @ruddell for testing!
@duderoot no https://github.com/jhipster/jhipster/pull/59 has not been merged yet, it's one of those old PRs I didn't have time to check. @gzsombor you're the boss on that part, can you do a review?
-> I'm not sure what we should do here, @agoncal can you check if that issue is fixed or not?
@ruddell @jdubois Fixed for me too ! #Great
OK so that's fixed - from my understanding the PR from @ctamisier fixed this, is that correct? I'm asking because there's a $100 bug bounty for this, and our rule is to give it to the person who did the PR
Sorry I should have read @duderoot's comment more closely.  The issue is mostly fixed, but not when entity-filtering is enabled (which should be fixed by that PR I'm guessing).  To reproduce, add filter * and service * with mapstruct to the JDL
If back end will support specified filter on references (possible solution is @duderoot's back end improvement https://github.com/jhipster/jhipster/pull/59 - this worked in my case) then possible solution in front end is:
replace
                query = `this.${relationship.otherEntityName}Service
            .query({filter: '${relationship.otherEntityRelationshipName.toLowerCase()}-is-null'})
with
                let filter = `filter: '${relationship.otherEntityRelationshipName.toLowerCase()}-is-null'`;
                if (this.jpaMetamodelFiltering) {
                    filter = `jpaMetamodelFilter: '${relationship.otherEntityRelationshipName}Id.specified=false'`;
                }
                query = `this.${relationship.otherEntityName}Service
            .query({${filter}})
replace
            if (key !== 'sort') {
with
            if (key === 'jpaMetamodelFilter') {
                const filter = req[key].split('=');
                options = options.append(filter[0], filter[1]);
            } else if (key !== 'sort') {
Thanks a lot @kaidohallik but I just tested your fix and it didn't make any difference.... I'm going to do a PR with your change and link it here, if someone wants to check.
For the record, here is the JDL that fails:
entity Sponsor (sponsor) {
  name String
}
entity SponsorAgreement (sponsor_agreement) {
  total Float
}
relationship OneToOne {
  SponsorAgreement{sponsor required} to Sponsor{sponsorAgreement}
}
filter *
dto * with mapstruct
service * with serviceClass
Otherwise this is a very specific use case, and this has been opened for a very long time, even with the $100 tag, so at some point we'll need to close this.
Finally, it was merged 👍 _"Das war eine schwere Geburt"_ it's a German saying that will summarize this issue. It means something like _"Well, that took some doing"_ Happy to see it done 😃
Most helpful comment
Finally, it was merged 👍 _"Das war eine schwere Geburt"_ it's a German saying that will summarize this issue. It means something like _"Well, that took some doing"_ Happy to see it done 😃