5

I need help to define correctly a @OneToMany JPA annotation. Tried different ways but still get error/issues like the foreign key (visitor_revision_id) is null in the visitorCharacteristic table.

I would like to join the 2 tables with the "visitor_revision_id"

@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
@ToString
public class Visitor {
    @Id
    @Column(name="visitor_revision_id")
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    Long id;

    String visitorCode;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "visitor")
    List<VisitorCharacteristic> visitorCharacteristicList;
}

@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
@ToString
class VisitorCharacteristic {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    Long id;

    @JoinColumn(name = "visitor_revision_id")
    @ManyToOne(optional = false) //fetch = FetchType.EAGER, cascade =  CascadeType.ALL)
    Visitor visitor;

    @Column(nullable = false)
    String attributeCode;

    @Column(nullable = false)
    String attributeValue;    
}

Thanks in advance for your help

GeorgesD
  • 73
  • 1
  • 1
  • 6

5 Answers5

10

JPA will not set VisitorCharacteristic#visitor field for you, you have to do it manually. If you have some method for adding subsequent VisitorCharacteristics, you should add the code for setting visitor in characteristic as well:

public void addVisitorCharacteristic(VisitorCharacteristic visitorCharacteristic) {
    if (visitorCharacteristicList == null) {
        visitorCharacteristicList = new ArrayList<>();
    }
    visitorCharacteristic.visitor = this;
    visitorCharacteristicList.add(visitorCharacteristic);
}

Here you can find a Gist with your code which works well - look at the line 79.

Maciej Dobrowolski
  • 11,561
  • 5
  • 45
  • 67
1

Without a test case showing the failure its difficult to tell.

Here are some things you can try:

  1. add , nullable = false to the join column annotation on VisitorCharacteristic

  2. set the relationship in both directions Visitor v = new Visitor(); VisitorCharacteristic vc = new VisitorCharacteristic(); v.setVisitorCharacteristicList(Arrays.asList(vc)); vc.setVisitor(v);

Bob Lukens
  • 700
  • 6
  • 10
1

class Visitor

public class Visitor {
    @Id
    @Column(name = "visitor_revision_id")
    @GeneratedValue
    Long id;

    @Column
    String visitorCode;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "visitor_revision_id", referencedColumnName = "visitor_revision_id")
    List<VisitorCharacteristic> visitorCharacteristicList;
}

VisitorCharacteristic

public class VisitorCharacteristic {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;

    @Column
    String attributeCode;
    @Column
    String attributeValue;
}
Pang
  • 9,564
  • 146
  • 81
  • 122
1

You can achieve it by annotating as follows:

@RepositoryRestResource(export = false) on VisitorCharacteristicRepository

and creating your own custom controller For VisitorCharacteristic.

For more understanding you can see - https://youtu.be/FRvtVf9sVjs

Alex Yu
  • 3,412
  • 1
  • 25
  • 38
0

I have 2 tables : Users and Wallets I wanted to link these two tables with FK relationship and I was using hibernate with Repository pattern.

When I was doing following I was getting : ERROR: null value in column "user_id" of relation "wallet" violates not-null constraint

Details : [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [user_id" of relation "wallet]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement]

    Wallet wallet = new Wallet();
    wallet.setAccountsSet(Set.of("creditAccount", "debitAccount"));

    Users user = UsersMapper
            .dtoToEntity(usersDto       
            .setWalletDtoSet(
              Set.of(WalletMapper.entityToDto(wallet)))
            );
   
    this.usersRepository.save(user);

Root Cause : There was not null constraint on the FK in Wallet table. Removing not-null constraint resolved the issue of constraint violation - user_id is null

Tables :

CREATE TABLE public.users (
id varchar NOT NULL,
is_active bool NOT NULL DEFAULT true,
created_by varchar NOT NULL,
creation_timestamp timestamptz NOT NULL DEFAULT now(),
updated_by varchar NULL,
update_timestamp timestamptz NOT NULL DEFAULT now(),
CONSTRAINT users_uuid_pk PRIMARY KEY (uuid)
);


CREATE TABLE public.wallet (
wallet_id int4 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
user_id varchar NULL,
CONSTRAINT wallet_wallet_id_pk PRIMARY KEY (wallet_id),
CONSTRAINT wallet_user_uuid_fk FOREIGN KEY (user_uuid) REFERENCES public.users(uuid)
);
Harshil
  • 1,230
  • 17
  • 22