Reputation: 99
I have a problem with persisting children entities even though I'm using a CascadeType.PERSIST. When i add new children object to a parent it's persisted but it's fields are made null.
My Entities:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
public class Portfolio {
@Id
@GeneratedValue
private Long id;
private String ownerEmail;
private Long roomId;
private Double startingCash;
@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST})
private List<PortfolioState> states;
}
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
public class PortfolioState {
@Id
@GeneratedValue
private Long id;
private Date fromDate;
private Date to;
private Double cash;
@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.REFRESH})
private List<Position> positions;
}
When the following lines of code get executed, PortfolioState get's persisted with all except id as null.
/*Adding a new PortfolioState to Portofolio's states */
System.out.println(" Portfolio : " + portfolio.toString());
Portfolio savedPortfolio = portfolioRepository.save(portfolio);
System.out.println(" Saved portfolio : " + savedPortfolio.toString());
System.out.println(" Portfolio object after saving " + portfolio.toString());
Portfolio : Portfolio(id=1, [email protected], roomId=1, startingCash=1000.0, states=[PortfolioState(id=2, fromDate=2020-01-01 00:00:00.0, to=Mon Jan 06 00:00:00 CET 2020, cash=300.0, positions=[Position(id=3, ticker=MSFT, quantity=2), Position(id=4, ticker=AAPL, quantity=3)]), PortfolioState(id=null, fromDate=Tue Jan 07 00:00:00 CET 2020, to=Sun Sep 14 02:00:00 CEST 3197, cash=290.28, positions=[Position(id=null, ticker=MSFT, quantity=2), Position(id=null, ticker=AAPL, quantity=3), Position(id=null, ticker=NIO, quantity=3)])])
Saved portfolio : Portfolio(id=1, [email protected], roomId=1, startingCash=1000.0, states=[PortfolioState(id=2, fromDate=2020-01-01 00:00:00.0, to=Mon Jan 06 00:00:00 CET 2020, cash=300.0, positions=[Position(id=3, ticker=MSFT, quantity=2), Position(id=4, ticker=AAPL, quantity=3)]), PortfolioState(id=5, fromDate=null, to=null, cash=null, positions=null)])
Portfolio object after saving Portfolio(id=1, [email protected], roomId=1, startingCash=1000.0, states=[PortfolioState(id=2, fromDate=2020-01-01 00:00:00.0, to=Mon Jan 06 00:00:00 CET 2020, cash=300.0, positions=[Position(id=3, ticker=MSFT, quantity=2), Position(id=4, ticker=AAPL, quantity=3)]), PortfolioState(id=5, fromDate=null, to=null, cash=null, positions=null)])
I've tried fixing this issue by using CascadeType.MERGE along with PERSIST, but it results in states duplicating. I'm using h2-in-memory database and plain JPA without hibernate. I'm using a default save method from JPARepository interface. Can you explain what and why is happening ? How do i fix this ?
Upvotes: 0
Views: 1164
Reputation: 99
@FelixSeifert helped me figured out this one. It seems that FetchType.EAGER
was causing the problem. I've switched to FetchType.LAZY
and CascadeType.ALL
. I've also added a bidirectional @ManyToOne
in PortfolioState.java.
public class Portfolio implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String ownerEmail;
private Long roomId;
private Double startingCash;
@OneToMany(
cascade = {CascadeType.ALL},
orphanRemoval = true
)
private List<PortfolioState> states = new ArrayList<>();
}
public class PortfolioState implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Date fromDate;
private Date to;
private Double cash;
@OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<Position> positions = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
private Portfolio portfolio;
}
Upvotes: 1