Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Inserting a column that has refs to other entities in Java Spring JPA

I am creating a database that keeps information about other database and I want ot insert an entry. Classes look like:

@Entity
@Table(name = "table_info")
public class TableInfo {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @OneToOne
    @JoinColumn(name = "database_id")
    private DatabaseInfo databaseInfo;

    @Column(name = "table_name", length = 255, nullable = false)
    private String tableName;

    @Column(name = "created_at")
    private Timestamp createdAt;
    // Getter Setters, etc
}
@Entity(name = "UserInfo")
@Table(
        name = "UserInfo",
        uniqueConstraints = {
                @UniqueConstraint(name = "user_unique", columnNames = "username")
        }
)
public class UserInfo {

    @Id
    @SequenceGenerator(
            name = "userinfo_sequence",
            sequenceName = "userinfo_sequence",
            allocationSize = 1
    )
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "userinfo_sequence"
    )
    @Column(
            name = "id",
            updatable = false
    )
    private Long id;

    @Column(
            name = "masterID",
            updatable = true,
            nullable = false
    )
    private Long masterID;

    @Column(
            name = "username",
            updatable = false,
            nullable = false,
            columnDefinition = "TEXT"
    )
    private String username;

    @Column(
            name = "email",
            updatable = false,
            nullable = false,
            columnDefinition = "TEXT"
    )
    private String email;

    @Column(
            name = "password_hash",
            updatable = true,
            nullable = false,
            columnDefinition = "TEXT"
    )
    private String password_hash;
    // Getter Setters, etc

}

@Entity
@Table(name = "ownership_details")
public class OwnershipDetails {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ownership_details_id")
    private Long id;

    @Column(name = "access_level")
    private Integer access_level;

    @OneToOne(
            cascade = CascadeType.MERGE,
            fetch = FetchType.LAZY,
            orphanRemoval = true
    )
    @JoinColumn(name = "user_id", referencedColumnName = "id")
    private UserInfo user;

    @OneToOne(
        cascade = CascadeType.MERGE,
        fetch = FetchType.LAZY,
        orphanRemoval = true
    )
    @JoinColumn(name = "table_id", referencedColumnName = "id")
    private TableInfo tableInfo;
}

Here is my OwnershipDetails repository:

@Repository
public interface OwnershipDetailsRepository extends JpaRepository<OwnershipDetails, Long> {
    
}

Whenever I try to insert new OwnershipDetails object I simply use:
ownershipDetailsRepository.save(ownershipDetails);

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Whenever I do that I get an error:
not-null property references a null or transient value : project.BackEnd.User.UserInfo.email
Which obviously means that it is trying to insert a new userInfo object instead of creating a reference to the one that already exists. My question is how can I force it to create refs instead of trying to create another entity in database.

>Solution :

Indeed, it is trying to insert a new userInfo object instead of creating a reference to the one that already exists.

You have to first get a reference to the persistent UserInfo entity by using getReferenceById, findById or any other finder method, then set the UserInfo entity on the OwnershipDetails before saving.

Whenever you try to insert new OwnershipDetails, Spring Data JPA detects that it’s a new entity and calls em.persist.
CascadeType.MERGE is not used in this case as it relates to merge operations on the parent entity, not persist.
So Hibernate complains that it’s trying to persist a detached UserInfo instance (and does not try to persist it because CascadeType.PERSIST is not defined).

var user = userInfoRepository.getReferenceById(userInfoId);
// build ownershipDetails
ownershipDetails.setUser(user);
ownershipDetailsRepository.save(ownershipDetails);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading