Spring data JPA. Add record (insert data) as "foreign key id" opposed to as a "entity". Is there a difference?

Viewed 9

I couldn't find the answer to my question, I hope this is not a duplicate question. Below is illustrated made-up example.

Database model database model

data table "user":

+--+--------+
|id|username|
+--+--------+
|1 |someUser|
+--+--------+

I would like to know what is the difference when:

  1. Entity (contact) is saved to the database in a way where 'userId' is mapped as a foreign key value (eg. 1)
  2. Entity (contact) saved is to the database in a way where 'userId' is used to retrieve the respective User entity from the database and set to contact.

Controller

@RestController
public class ContactController {
    // to keep is short, all action is here in controller
    @Resource
    private ContactMapper contactMapper;

    @Resource
    private ContactRepository contactRepository;
    
    @Resource
    private UserRepository userRepository;

    @PostMapping("/as-foreign-key")
    public void addContactWithUserIdForeignKey(@RequestBody ContactDto dto) {
        Contact contact = contactMapper.contactDtoToContact(dto);
        contactRepository.save(contact);
    }

    @PostMapping("/as-entity")
    public void addContactWithUserEntity(@RequestBody ContactDto dto) {
        User user = userRepository.findById(dto.getUserId()).get();

        Contact contact = contactMapper.contactDtoToContact(dto);
        contact.setUser(user);
        contactRepository.save(contact);
    }

}

DTO

@Data
public class ContactDto implements Serializable {
    private final String firstName;
    private final String lastName;
    private final Integer userId;
}

MapStruct mapper

@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = "spring")
public interface ContactMapper {

    @Mapping(source = "userId", target = "user.id")
    Contact contactDtoToContact(ContactDto contactDto);

}

Entities

@Data
@Entity
@Table(name = "\"user\"")
public class User {
    @Id
    @Column(name = "id", nullable = false)
    private Integer id;

    @Column(name = "username", nullable = false, length = 50)
    private String username;
}
@Data
@Entity
@Table(name = "contact")
public class Contact {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Integer id;

    @Column(name = "first_name", nullable = false, length = 50)
    private String firstName;

    @Column(name = "last_name", nullable = false, length = 50)
    private String lastName;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "user_id", nullable = false)
    private User user;
}

Executing both requests:

curl -X 'POST' \
  'http://localhost:8080/as-foreign-key' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -d '{
  "firstName": "John",
  "lastName": "Doe",
  "userId": 1
}'
curl -X 'POST' \
  'http://localhost:8080/as-entity' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -d '{
  "firstName": "Jane",
  "lastName": "Done",
  "userId": 1
}

Result

data table "contact":

+--+----------+---------+-------+
|id|first_name|last_name|user_id|
+--+----------+---------+-------+
|1 |John      |Doe      |1      |
|2 |Jane      |Done     |1      |
+--+----------+---------+-------+

Both ways produce the same result.

Looking from console, I can see the following hibernate SQL statements.

Hibernate: select user_.id, user_.username as username2_1_ from "user" user_ where user_.id=?
Hibernate: insert into contact (first_name, last_name, user_id) values (?, ?, ?)

Hibernate: select user0_.id as id1_1_0_, user0_.username as username2_1_0_ from "user" user0_ where user0_.id=?
Hibernate: insert into contact (first_name, last_name, user_id) values (?, ?, ?)

So far I have always thought that the correct way is the second way: first, find the Entity (user), use setter, and then save.

Is there any technical difference between these two approaches? Could I safely go via the first way or is there something that I should consider?

Any info around this subject is much appreciated.

0 Answers
Related