# Generator class "foreign" does not actually generate anything

**URL:** <https://discourse.hibernate.org/t/generator-class-foreign-does-not-actually-generate-anything/7208>\
**Category:** Hibernate ORM\
**Created:** [January 30, 2023, 7:11pm UTC](https://discourse.hibernate.org/t/generator-class-foreign-does-not-actually-generate-anything/7208 "2023-01-30T19:11:31Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![asdf\_username](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/asdf_username/32/2229_2.png) [@asdf\_username](https://discourse.hibernate.org/u/asdf_username)\
**Post date:** [January 30, 2023, 7:11pm UTC](https://discourse.hibernate.org/t/generator-class-foreign-does-not-actually-generate-anything/7208/1 "2023-01-30T19:11:31Z")

</div>

There seems to be no automated way to pass a parent’s generated ID value into the children of an object where applicable, even when `<generator class="foreign">` is specified in the child.

For example:

Say you have the following relation - A company can have a PIA agreement, but is not required to have one. Your hbm xml configuration would look something like this:

Company.hbm.xml

```
<hibernate-mapping>
    <class name="com.something.something.something.Company" table="COMPANY">
        <id name="id" column="ID">
            <generator class="increment"/>
        </id>

        <property name="name" column="NAME"/>
        
        <one-to-one name="pia" class="com.iti.dexcenter.common.object.Pia" cascade="all-delete-orphan" foreign-key="companyId"/>
    </class>
</hibernate-mapping>

```

Pia.hbm.xml

```
<hibernate-mapping>
    <class name="com.iti.dexcenter.common.object.Pia" table="PIA">
        <id name="companyId" column="company_id">
            <generator class="foreign">
                <param name="property">company</param>
            </generator>
        </id>

        <property name="agreementNumber" column="AGREEMENT_NUMBER"/>
        <one-to-one name="company" class="com.something.something.something.Company" />
    </class>
</hibernate-mapping>

```

Then, when I call `.save(company)` to add the company entry (and the pia entry if one is provided) to the DB, you get this error regardless of whether a pia is set on the company object:

`attempted to assign id from null one-to-one property [com.something.something.something.Pia.company]; nested exception is org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [com.something.something.something.Pia.company]`

The issue has been reported by many other people without a proper resolution:

> <https://stackoverflow.com/questions/11104897/hibernate-attempted-to-assign-id-from-null-one-to-one-property-employee>

Basically, you need to do this bizarre thing here

```
    if(company.getPia() != null) {
        company.getPia().setCompany(company);
    }

```

Before you call .save(), as you can see:

```
@Override
@Transactional
public int insertCompany(Company company) {
    int result = -1;

    if(company.getPia() != null) {
        company.getPia().setCompany(company);
    }

    try {
        template.save(company);
        result = company.getId();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return result;
}

```

\*\*\*If you don’t do those 3 lines before calling .save(), you’ll get the error mentioned in the stackoverflow post. Why is this necessary??? \*\*\*

Some more code…

Company.java (POJO)

```
public class Company {

    private Integer id;
    private String name;
    private Pia pia;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public void setPia(Pia pia) { this.pia = pia; }
    public Pia getPia() {
        return pia;
    }
    
}

```

Pia.java (POJO)

```
public class Pia {

    private Integer companyId;
    private String agreementNumber;
    private Company company;

    public Integer getCompanyId() {
        return companyId;
    }
    public void setCompanyId(Integer companyId) {
        this.companyId = companyId;
    }

    public String getAgreementNumber() {
        return agreementNumber;
    }
    public void setAgreementNumber(String agreementNumber) {
        this.agreementNumber = agreementNumber;
    }

    public Company getCompany() {return company;}
    public void setCompany(Company company) { this.company = company; }

}

```

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [January 31, 2023, 11:16am UTC](https://discourse.hibernate.org/t/generator-class-foreign-does-not-actually-generate-anything/7208/2 "2023-01-31T11:16:15Z")

</div>

I think that you might be missing `property-ref="company"` on `<one-to-one name="pia" class="com.something.something.something.Pia" outer-join="true" fetch="join" cascade="all-delete-orphan" lazy="false"/>` to make this work. Also see [[HHH-12436] - Hibernate JIRA](https://hibernate.atlassian.net/browse/HHH-12436) which seems relevant here.

---

<div class="post-metadata">

**Author:** ![asdf\_username](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/asdf_username/32/2229_2.png) [@asdf\_username](https://discourse.hibernate.org/u/asdf_username)\
**Post date:** [January 31, 2023, 3:25pm UTC](https://discourse.hibernate.org/t/generator-class-foreign-does-not-actually-generate-anything/7208/3 "2023-01-31T15:25:09Z")

</div>

Hi, unfortunately after trying this suggestion I am still needing to call

```
if(company.getPia() != null) {
    company.getPia().setCompany(company);
}

```

Or else I still see the error “attempted to assign id from null one-to-one property [com.something.something.something.Pia.company]”.

The above code is needed before calling `.save()` or I get that error, and also need it before  
UPDATE. Actually, for update to work in all cases regardless of a pia already exists or not for a given company, I have to use .merge() and .saveOrUpdate() depending on whether the pia passed is null, so another non-automated / manual step.

```
@Transactional
@Override
public int updateCompany(Company company) {
    int result = 0;
    try {
        if(company.getPia() != null) {
            // don't ask why this line is needed
            company.getPia().setCompany(company);

            template.saveOrUpdate(company);
        } else {
            // This was the only thing that worked to remove the pia for a company if no pia was passed in the company object.
            template.merge(company);
        }
        result = 1;
    } catch (Exception e) {
        e.printStackTrace();
        logger.error(e);
        logger.error(e.getMessage());
    }
    return result;
}

```

Also unsure why I need to call `.merge(company)` to delete the pia from the db if I pass a company object that has pia set to null. Instead of “merge” also tried:

`Company thisCompany = findCompanyByCompanyId(company.getId()); template.delete(thisCompany.getPia());`

But this gave me the error

`Error during managed flush [deleted object would be re-saved by cascade (remove deleted object from associations): [com.something.something.something.Pia#14]]`

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [February 1, 2023, 2:38pm UTC](https://discourse.hibernate.org/t/generator-class-foreign-does-not-actually-generate-anything/7208/4 "2023-02-01T14:38:05Z")

</div>

> Hi, unfortunately after trying this suggestion I am still needing to call

Well, you should always maintain both sides of a bidirectional association, but in this particular case, it is `Pia#company` that is the “owner” of this bidirectional association, so it is that field/attribute which Hibernate uses to determine the foreign key column value. Usually, people define the setters on the inverse side like this to avoid the problem:

```java
public void setPia(Pia pia) {
    this.pia = pia;
    if ( pia != null ) {
        pia.setCompany(this);
    }
}

```

> Also unsure why I need to call .merge(company) to delete the pia from the db if I pass a company object that has pia set to null. Instead of “merge” also tried:

I don’t understand your confusion. You want a `Pia` entity to be deleted, so you have two options, call `EntityManager.remove(pia)` or cause some orphan removal through an attribute cascade. Using `EntityManager.merge(company)` essentially will trigger that orphan removal, because that is how you specified the `one-to-one` association `Company#pia`.

> Instead of “merge” also tried:

You see this error because when you run that code, you first load a company into the persistence context, which is then managed at this point. Since `Company#pia` specifies to cascade all operations, the “flush” of the persistence context will eventually make sure that the object graph is synchronized with the database.  
Since you now try to delete a `Pia` object, there is a kind of conflict. Your explicit `EntityManager#remove` call via `template.delete(..)` marks the object as removed, but during the “flush” of the persistence context, it would be re-persisted. So what should Hibernate do in this case? It does the sensible thing and tells you about this inconsistency in your object graph. If you want to remove the `Pia` object, also make sure that you don’t refer to it anymore from managed entities.

---

<div class="post-metadata">

**Author:** ![asdf\_username](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/asdf_username/32/2229_2.png) [@asdf\_username](https://discourse.hibernate.org/u/asdf_username)\
**Post date:** [February 1, 2023, 5:36pm UTC](https://discourse.hibernate.org/t/generator-class-foreign-does-not-actually-generate-anything/7208/5 "2023-02-01T17:36:04Z")

</div>

I think this is starting to make sense! Thank you for your patience in helping me 🙂 for some reason I didn’t think that in a 1-to-0or1 relationship you needed to define the relationship on both sides / in both hbm xml files. Then when I added it I got a lot closer.

`Your explicit EntityManager#remove call via template.delete(..) marks the object as removed, but during the “flush” of the persistence context, it would be re-persisted.`

So inside my @Transactional marked Java method, if I manually fetch an entity from the DB using .find() to get a parent that contains a child, I can’t delete the child (pia) from that managed parent… Can I delete anything from a managed entity, such as the parent itself if there was no foreign key / if the parent was not part of a 1-to-1 relationship? Or is it related to what is inside @Transactional that determines the object graph being in sync / not being in sync?

For example, in the below method, if I were to change the method to `deleteCompany(Company company)` instead of passing in an ID, would I be able to just do  
`template.delete(company);`,  
instead of setting the pia to null in the loaded/managed “thisCompany” then merging? Or would I just need to do

```
 template.delete(company.getPia()); 
 template.delete(company); 

```

I think based on what you said, the below code is working because when I manually fetch an entity from the DB using “findCompanyByCompanyId()” in a method that has the word @Transactional in it, the object graph is not in sync, which is why I have to “merge” to delete the Pia entry - I’m merging the object graph with the db basically. Whereas if I pass in a company object with a null Pia, the graphs are synced from the start since it was passed in, so I wouldn’t need to call .merge() to delete the Pia ?

(Delete company method that is working)

```
@Override
@Transactional
public boolean deleteCompany(int companyId) {
    boolean result = false;
    try {
        Company thisCompany = findCompanyByCompanyId(companyId);
        thisCompany.setPia(null);
        template.merge(thisCompany);

        template.delete(thisCompany);
        result = true;
    } catch (Exception e) {
        result = false;
        e.printStackTrace();
    }
    return result;
}

```

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [February 1, 2023, 5:55pm UTC](https://discourse.hibernate.org/t/generator-class-foreign-does-not-actually-generate-anything/7208/6 "2023-02-01T17:55:06Z")

</div>

If you also want to delete the company, then you could just rely on delete cascading. The `Company#pia` association already defines `cascade="all-delete-orphan"`, so you don’t have to delete `Pia` explicitly, Hibernate will take care of that.

> if I manually fetch an entity from the DB using .find() to get a parent that contains a child, I can’t delete the child (pia) from that managed parent

The problem is that the managed parent is going to be flushed before transaction commit, but since you marked the `Pia` object as removed, a conflict appears during flushing of the `Company`/parent, because `Company#pia` wants to cascade (that’s what you configured), but runs into this conflict. So if you want to delete the `Pia` separately, you have to call `company.setPia(null)`, so that cascading does not run into a conflict.

So, since you have delete cascading setup, you can just write this:

```java
@Override
@Transactional
public boolean deleteCompany(int companyId) {
    template.delete(findCompanyByCompanyId(companyId));
}

```

---

<div class="post-metadata">

**Author:** ![asdf\_username](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/asdf_username/32/2229_2.png) [@asdf\_username](https://discourse.hibernate.org/u/asdf_username)\
**Post date:** [February 1, 2023, 7:15pm UTC](https://discourse.hibernate.org/t/generator-class-foreign-does-not-actually-generate-anything/7208/7 "2023-02-01T19:15:23Z")

</div>

That deleteCompany tweak you suggested worked! looks a lot cleaner too now… Thanks.

Changing the setter in Company.java (as you suggested) did work and now I no longer need those manual 3 lines in there before every call to .save() or .saveOrUpdate()!

```
public void setPia(Pia pia) {
    this.pia = pia;
    if ( pia != null ) {
        pia.setCompany(this);
    }
}

```

In the setter, why is there `pia.setCompany(this)`, and not `this.pia.setCompany(this)`?  
I see there is the line `this.pia = pia;` above that, is it like Javascript how sometimes when you set a variable to another variable it “syncs” them / when you update one it updates the other, unless you use JSON.parse(JSON.stringify(myObj)) to make a “clone without reference”? So similarly when we do `pia.setCompany(this)`, it is also changing `this.pia` when we do `pia.setCompany(this)` because because we did `this.pia = pia` above it?

Also, **why don’t I need an “else”** on the condition in the setter, something like

```
if ( pia != null ) {
        pia.setCompany(this);
    } else {
       pia.setCompany(null);
}

```

* * *

So the reason I cannot call this code to delete a pia

```
Company thisCompany = findCompanyByCompanyId(company.getId()); 
template.delete(thisCompany.getPia());

```

is because of my cascade setting `cascade="all-delete-orphan"`. It is a bit strange to a new user that this works:

```
Company thisCompany = findCompanyByCompanyId(company.getId());
thisCompany.setPia(null);
template.delete(thisCompany.getPia());

```

One would think this would give the same result as doing JUST  
`template.delete(null)`,  
since if you were to do thisCompany.setPia(null), then `thisCompany.getPia()` evaluates to null.

But instead if you do JUST  
`template.delete(null)`, you get `java.lang.IllegalArgumentException: attempt to create delete event with null entity`.

HOWEVER,  
this works:

```
Company thisCompany = findCompanyByCompanyId(company.getId());
thisCompany.setPia(null);
template.delete(null);

```

So it seems what you pass to .delete() doesn’t really affect much? .delete() is basically just doing a commit of the .setPia(null) we did because of the `flush` you mentioned that it does before update/save/delete, and flush also commits, which lines up/syncs/updates the db row that matches the pk with the CURRENT STATE OF THE JAVA OBJECT? 🤔

SO I technically could also do:

```
Company thisCompany = findCompanyByCompanyId(company.getId());
thisCompany.setPia(null);
template.flush();

```

?

(newly updated updateCompany() method)

```
@Transactional
@Override
public int updateCompany(Company company) {
    int result = 0;
    try {
        if(company.getPia() != null) {
            template.saveOrUpdate(company);
        } else {
            // Does not work:
            // Company thisCompany = findCompanyByCompanyId(company.getId());
            // template.delete(thisCompany.getPia());
            // (gives error "deleted object would be re-saved by cascade")

            // Works:
            // Company thisCompany = findCompanyByCompanyId(company.getId());
            // thisCompany.setPia(null);
            // template.delete(thisCompany.getPia());

            // Also works:
            // Company thisCompany = findCompanyByCompanyId(company.getId());
            // thisCompany.setPia(null);
            // template.delete(null);

            // Works and is the least code:
            template.merge(company);
        }
        result = 1;
    } catch (Exception e) {
        e.printStackTrace();
        logger.error(e);
        logger.error(e.getMessage());
    }
    return result;
}

```

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [February 2, 2023, 1:58pm UTC](https://discourse.hibernate.org/t/generator-class-foreign-does-not-actually-generate-anything/7208/8 "2023-02-02T13:58:03Z")

</div>

> In the setter, why is there `pia.setCompany(this)` , and not `this.pia.setCompany(this)` ?

Since you set the field `pia` of the `this` object to the object the local variable `pia` refers to, both `pia` and `this.pia` resolve to the same object after the `this.pia = pia;` assignment, so you can use both variants as they do the same.

> Also, why don’t I need an “else” on the condition in the setter, something like

You can surely do that. My examples are just that, examples, not the perfect code that you should use 1:1 in your project 😉

> is because of my cascade setting `cascade="all-delete-orphan"` . It is a bit strange to a new user that this works:

I have no idea what this `template` is, but it is not part of Hibernate, so I can’t help you with that.

> SO I technically could also do:

Yes, now you seem to slowly understand the concept of managed entities. The idea is that you don’t have to tell the ORM “update this” and “delete that”, but instead you can most of the time just change object state of managed entities and the ORM will figure out what commands to send to the database.

I don’t know why you think you need the `saveOrUpdate` part. This should suffice:

```java
@Transactional
@Override
public int updateCompany(Company company) {
    int result = 0;
    try {
        template.merge(company);
        result = 1;
    } catch (Exception e) {
        e.printStackTrace();
        logger.error(e);
        logger.error(e.getMessage());
    }
    return result;
}

```

---

<div class="post-metadata">

**Author:** ![asdf\_username](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/asdf_username/32/2229_2.png) [@asdf\_username](https://discourse.hibernate.org/u/asdf_username)\
**Post date:** [February 2, 2023, 9:28pm UTC](https://discourse.hibernate.org/t/generator-class-foreign-does-not-actually-generate-anything/7208/9 "2023-02-02T21:28:02Z")

</div>

Thanks again…

`I have no idea what this 'template' is, but it is not part of Hibernate`

I have no idea what `template` is either LOL  
I see it is defined here in the parent DAO java class as:  
`protected HibernateTemplate template;`  
Then in the child DAO classes like the one where updateCompany/findCompany/deleteCompany are in (one dao file for companies methods, one dao file for users methods, etc.)  
we add  
`extends HBaseDAOImpl`  
and  
` public HCompanyDAOImpl(HibernateTemplate template) { this.template = template; }`

Not sure what the difference is between HibernateTemplate and a Session is, though. Been wondering for so long why other people’s code looks so different from ours since they just use variables called “session”.

I’m not really sure why I thought an else was needed here, been running on little sleep this week

```
if ( pia != null ) {
    pia.setCompany(this);
} else {
   pia.setCompany(null);
}

```

That else condition will guarantee a null pointer exception.

* * *

One last thing…

**Why might I need this “@JsonIgnore()”**

```
// the annotation prevents a stack overflow error when loading a company with a pia
@JsonIgnore()
private Company company;

```

In the POJO Pia.java when I call .find()?

When the annotation was not there, I got my first-ever StackOverflow exception in Java and a “ **Response already committed** ” message. But I’m just using .find() to load a company, why would it think something was committed? Note: “DataAccessUtils” is some Spring thing, it will throw an “unexpected row count” error if it returns more than 1 row basically. I don’t think that piece of info should affect why Pia.java needs @JsonIgnore, though.

```
@Override
public Company findCompanyByCompanyId(int companyId) {
    return (Company) DataAccessUtils.singleResult(template.find("from Company where id=?0", companyId));
}

```

without @JsonIgnore() in Pia.java gives

```
WARN [org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.handleHttpMessageNotWritable()] (default task-8) Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.something.something.something.Pia["company"]->com.something.something.something.Company["pia"]->com.something.something.something.Pia["company"]->...
WARN [org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.doResolveException()] (default task-8) Handling of [org.springframework.http.converter.HttpMessageNotWritableException] resulted in Exception
java.lang.IllegalStateException: UT010019: Response already commited

```

Snippet from Pia.java:

```
 public Company getCompany() { return company; }
 public void setCompany(Company company) {
     this.company = company;
 }

```

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [February 3, 2023, 8:57am UTC](https://discourse.hibernate.org/t/generator-class-foreign-does-not-actually-generate-anything/7208/10 "2023-02-03T08:57:42Z")

</div>

Since you seem to be serializing (implicitly) the company to JSON through some HTTP endpoint, you have to tell the JSON serializer (in your case Jackson) to not serialize certain fields/properties (by annotating `@JsonIgnore`), because doing so would result in a cycle which JSON can’t handle. The stack overflow is what happens when you serialize a `Company` then go to serialize the `Pia` and then back to the same `Company` again, and the exception message actually even tells you that:

> com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.something.something.something.Pia[“company”]-\>com.something.something.something.Company[“pia”]-\>com.something.something.something.Pia[“company”]-\>…

---

<div class="post-metadata">

**Author:** ![asdf\_username](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/asdf_username/32/2229_2.png) [@asdf\_username](https://discourse.hibernate.org/u/asdf_username)\
**Post date:** [February 5, 2023, 10:09pm UTC](https://discourse.hibernate.org/t/generator-class-foreign-does-not-actually-generate-anything/7208/11 "2023-02-05T22:09:12Z")

</div>

I thought we were approaching a resolution to the problem, but unfortunately there are still some things I’m confused about, even though it’s “working” now. It feels like it’s barely holding itself together and I’m almost tempted to just make Company and Pia completely separate and just manually set the IDs myself because this is just so much trial and error and this is going to make 0 sense to anyone who tries to pick up this code in the future, in our entire DB we don’t have ANY parent/child relationships that have been automated via Hibernate, we are manually setting the IDs for children using the parent, deleting each child first instead of the constraints cascading, and nothing is consistent. For how complicated this has been, I almost don’t blame them.

I also feel bad I’m still bugging you about this / that we’re still on this. It’s seeming like the “automation” benefits of hibernate with Parent and Child relationships are more trial and error than I’m actually seeing a benefit with. And the error messages are not helping me at all. **Half the time while I’ve been working through this, Hibernate has just been throwing “null pointer” exceptions on .save(), .update(), .delete(), .saveOrUpdate(), with 0 explanation why I’m actually getting an error, like they don’t even know why it’s not working, so they’re like “it didn’t work but we don’t know why so here’s a null pointer exception so you know something went wrong”.** Although this is not what I’m facing currently I feel like it’s worth mentioning. It doesn’t explain what property is null that shouldn’t be null, and why it shouldn’t be null. It could be ANYTHING in the object, a property in the child, or the parent. This is probably the simplest example of a 1-to-0or1 relationship that can possibly exist, and I’m still struggling hard.

* * *

It turns out using just

`template.merge(company);`

in updateCompany()

does not work, it doesn’t insert the Pia if one did not exist prior for a given company, and in this circumstance gives the same error originally mentioned in the post

```
 org.springframework.orm.hibernate5.HibernateSystemException: attempted to assign id from null one-to-one property [com.something.something.something.Pia.company]; nested exception is org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [com.something.something.something.Pia.company]

```

So updateCompany(Company company) needs to be structured as so (but why? why can’t I just use merge?):

```
 if(company.getPia() != null) {
      template.saveOrUpdate(company);
 } else {
      template.merge(company);
 }

```

I need this for it to update the way it should in all circumstances (If no pia existed previously, but I passed one in the Company object, then insert the pia.)

I’m still a little confused about the above, and also why in Pia.java I do not need my setter structured similarly to Company.java. If I were to structure it similarly to Company.java, then the 3 commented lines below would be uncommented:

```
public void setCompany(Company company) {
    // if (company != null) {
    // company.setPia(this);
    // }
    this.company = company;
}

```

Why is this not necessary, or is it?

I’m also still confused why I need the annotation @JsonIgnore in Pia.java, you mention `doing so would result in a cycle which JSON can’t handle` but I’m confused what the `doing so` part is referring to / what is causing the cycle in the first place. I’d like to know what is causing the infinite recursion because I have no code that could be causing in even a remotely obvious manner. I’m simply loading the Company object which contains a Pia using

```
@Override
public Company findCompanyByCompanyId(int companyId) {
    return (Company) DataAccessUtils.singleResult(template.find("from Company where id=?0", companyId));
}

```

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [February 6, 2023, 8:36am UTC](https://discourse.hibernate.org/t/generator-class-foreign-does-not-actually-generate-anything/7208/12 "2023-02-06T08:36:32Z")

</div>

> So updateCompany(Company company) needs to be structured as so (but why? why can’t I just use merge?):

Because you didn’t setup the bidirectionality in the object graph i.e. `Pia#company` is null, just like the error says.

> Why is this not necessary, or is it?

If you would do that, you would run into a stack overflow error because you’d recursively call the setters of the other which would go in circles.

> I’d like to know what is causing the infinite recursion because I have no code that could be causing in even a remotely obvious manner. I’m simply loading the Company object which contains a Pia using

Returning an object from your Spring WebMvc HTTP endpoint method will lead to serialization of this object. Depending on the resulting mime type, either to JSON or XML or whatever.

Don’t get me wrong, but I think you need some serious training or lot of learning from books as you seem to lack the very basics. This is a forum for questions about Hibernate, but your posts/questions more and more go into the very fundamentals of programming and the HTTP stack of Spring.  
So I’d like to ask you kindly to ask these questions elsewhere. You’re welcome to ask targeted questions about Hibernate in a new topic if something pops up.
