Spring Data Rest: POSTing entity with relation to non-exported entity

user3235738 :

I have an entity type that is exported via Spring Data Rest and has a relation to an entity which does not have it's own REST endpoint:

@Data
@NoArgsConstructor
@EqualsAndHashCode
@Entity
public class Request {

    ...

    @NotNull
    @OneToOne(cascade = CascadeType.ALL)
    @Immutable
    private Address address;

The "Address" type looks roughly like this plus the usual stuff for addresses ;)

@NoArgsConstructor
@Entity
@Getter
@Setter
public class Address {

    @Id
    @GeneratedValue
    private Long id;

There is a RequestRepo that extends CrudRepository but NO repository for the address type.

This is what I do: 1. GET a particular Request entity 2. Make a change to a property of Request (not address) 3. PUT the entire Request

I noticed, in the handler's @BeforeSave annotated method, that the address property has an id of "null". So it appears that instead of looking for that Address in the database, it simply created a new one.

Well, I understand that since the id is not POSTed there's not way to know which Address in the database this is supposed to be. That makes sense.

In the handler, I want to check if the address has been changed and then do things based on that information. Therefore, I fetch the old version of the Request from the database and compare the IDs of the two Addresses which of course results in a NullPointerException, since the ID of the posted Address is null. My quick solution would be to implement equals() omitting the ID and use that method to make the comparison.

But I wonder what other ways there might be. Any ideas?

Alan Hay :

I would make an address an Embeddable rather than an Entity: an address cannot exist without a Request and is not an Entity in its own right. You are unlikely to want to query for an Address. This may differ if you had many entities sharing the same address but it's a one-one-one so you don't.

You can keep the same database structure by using @SecondaryTable.

Request:

@Data
@NoArgsConstructor
@EqualsAndHashCode
@Entity
@Table(name = "requests")
@SecondaryTable("name = "addresses")
public class Request {

    @NotNull
    @Embedded
    private Address address;
}

Address:

@NoArgsConstructor
@Embeddable
@Getter
@Setter
public class Address {

    @Column(name="town", table="addresses")
    private String town;
}

Now on PUT the existing address will be updated.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=109367&siteId=1