curiousdev
curiousdev

Reputation: 636

object references an unsaved transient instance - save the transient instance before flushing - with CascadeType.ALL present

To start off, I will say that I have seen a lot of questions with the exact same exception message, however I did not find one that corresponded to the problem I'm having personally.

I have two classes that are related to one another as follows:

Parent class

public class MapArea {

    @Id
    @Column(nullable = false, unique = true)
    private String name;

    @ManyToOne(cascade=CascadeType.PERSIST)
    @OnDelete(action = OnDeleteAction.NO_ACTION)
    private MapArea parent;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "area")
    @JsonIgnore
    private Set<AlternativeAreaName> alternativeNames;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "data")
    private Set<MapAreaData> mapAreaData;

    @OneToOne(targetEntity = Expenses.class,
            cascade = CascadeType.ALL)
    @JoinColumn(name = "name", referencedColumnName = "area")
    private Expenses expenses;

    @OneToOne(targetEntity = Consumption.class,
            cascade = CascadeType.ALL)
    @JoinColumn(name = "name", referencedColumnName = "area")
    @JsonIgnore
    private Consumption consumption;

    @Transient
    private Set<RelatedMapArea> siblings;

    @Transient
    private Set<RelatedMapArea> children;

    ...
}

Child class

public class MapAreaData {

    @Id
    @JsonIgnore
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "num_bedrooms", nullable = false)
    private Integer numBedrooms;

    @Column(name = "property_type", nullable = false)
    @Enumerated(EnumType.STRING)
    private PropertyType propertyType;

    @OneToOne(targetEntity = Property.class,
            cascade = CascadeType.ALL)
    @JoinColumn(name = "property_id")
    private Property property;

    @OneToOne(targetEntity = Rent.class,
            cascade = CascadeType.ALL)
    @JoinColumn(name = "rent_id")
    private Rent rent;

    @OneToOne(targetEntity = CalculatedStats.class,
            cascade = CascadeType.ALL)
    @JoinColumn(name = "calculated_stats_id")
    private CalculatedStats calculatedStats;

    ...
}

Now the full error message that I get is this:

Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.topfind.search_api_common.map_area_data.MapAreaData

In similar questions, I have found that most people did not use a CascadeType which was their issue. However, in this case I am using CascadeType.ALL everywhere and I'd expect it to be able to save new children MapAreaData whenever I attempt to save MapArea.

I'd appreciate any ideas towards fixing the issue.

Edit 1

I'm initializing the data in one with the following code (keep in my any method starting with createMock* creates a new object with ALL variables (including nested objects that are related) populated, however it does not persist the created object.

        int top = 2;
        DataQuality dataQuality = DataQuality.ROUGH;

        MapArea ROUGH_mapArea = createMockArea("W5", null);
        MapAreaData ROUGH_mapAreaData = ROUGH_mapArea.getMapAreaData().iterator().next();
        ROUGH_mapAreaData.setCalculatedStats(createMockCalculatedStats(doubleToBigDecimal(15.43),
                DataQuality.ROUGH.getMinNumAnalysed(), DataQuality.GOOD.getMinNumAnalysed()));
        //ROUGH_mapAreaData = dataRepository.save(ROUGH_mapAreaData); - WORKS if this is used
        ROUGH_mapArea = mapAreaRepository.save(ROUGH_mapArea);

Upvotes: 1

Views: 328

Answers (1)

curiousdev
curiousdev

Reputation: 636

Turns out I had to specify a targetEntity to make it all work nicely together for Set<MapAreaData> in MapArea class as follows:

@OneToMany(targetEntity = MapAreaData.class, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "data")
private Set<MapAreaData> mapAreaData;

Upvotes: 1

Related Questions