When I save an entity that has a @JoinColumn
field that references another entity, it is saved correctly as expected by calling saveAndFlush()
. Now, I want to be able to return this entity along with its related entities back to the user. I assumed that calling getById()
with the ID of the newly saved entity will also retrieve @JoinColumn
values in the returned entity, however, the related entity of the returned entity contains the exact same values as the related entity that used in saveAndFlush()
. I have made example code to demonstrate what I'm talking about.
I send request:
GET http://localhost:8080
and receive as response:
{
"id": 3,
"name": "tests",
"related": {
"id": 3,
"name": null
}
}
My goal is to have the same request return the following response:
{
"id": 3,
"name": "tests",
"related": {
"id": 3,
"name": "test"
}
}
Where the related
contains name
along with id
which was specified in the saveAndFlush()
.
Controller.java
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
public class Controller {
private final ObjectRepository oRepo;
private final RelatedObjectRepository coRepo;
@GetMapping
private Object test() {
// imagine as if this entity is already present in the database before this request is handled, this line is only for context.
RelatedObject co = coRepo.saveAndFlush(new RelatedObject(null, "test"));
// create an instance of RelatedObject to contain the value for the related_id foreign key column.
RelatedObject nco = new RelatedObject(co.getId(), null);
// create Object and save it along with the referenced RelatedObject.
Object o = oRepo.saveAndFlush(new Object(null, "tests", nco));
// I expected all values of 'co' object to be contained in the result here in the @JoinColumn field 'related' of Object, instead, only 'id' is present like the 'nco' object
return oRepo.getById(o.getId());
}
}
Object.java
import lombok.*;
import javax.persistence.*;
@Table(name = "object")
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Object {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@Column(name = "name", length = 100)
private String name;
@ManyToOne
@JoinColumn(name = "related_id")
private RelatedObject related;
}
RelatedObject.java
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
@Table(name = "related_object")
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class RelatedObject {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Id", nullable = false)
private Long id;
@Column(name = "name", length = 100)
private String name;
}
ObjectRepository.java
import org.springframework.data.jpa.repository.JpaRepository;
public interface ObjectRepository extends JpaRepository<Object, Long> {
}
RelatedObjectRepository.java
import org.springframework.data.jpa.repository.JpaRepository;
public interface RelatedObjectRepository extends JpaRepository<RelatedObject, Long> {
}
SpringPlayGroundApplication.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringPlayGroundApplication {
public static void main(String[] args) {
SpringApplication.run(SpringPlayGroundApplication.class, args);
}
}
Alright, I figured out what I needed.
Associated entities needed to cascade refresh, for example:
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
@JoinColumn(name = "parent_id")
private Category parent;