0

This question is kindly related to a previous one here: getting null while posting data

I tryed a suggested answer, imported lombok and created a DTO class as follows:

package com.example.dto;
import java.util.HashSet;
import java.util.Set;

import lombok.Data;

@Data
public class TownDTO {
    public String name;
       public String regionid;
}

Table towns is related to a regions table in db. While I try to save data I am getting a following exception:

not-null property references a null or transient value : com.example.model.Towns.regionid

Here is my model class

package com.example.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

import com.fasterxml.jackson.annotation.JsonIgnore;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;


@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "towns")

public class Towns {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    @Column(name = "name")
    private String name;
    @JsonIgnore
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
        @JoinColumn(name = "regionid", nullable = false)
        @OnDelete(action = OnDeleteAction.CASCADE)
        private Regions regionid;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Regions getRegionid() {
        return regionid;
    }
    public void setRegionid(Regions regionid) {
        this.regionid = regionid;
    }
    
    
    
}

And repositories are as follows. Towns repository

package com.example.repository;
import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;

import com.example.model.Towns;
import com.example.model.Regions;
public interface TownsRepository extends JpaRepository<Towns, Integer> {

     List<Towns> findByNameContaining(String name);
     Page<Regions> findByregionid(Integer regionid, Pageable pageable);
        Optional<Regions> findByregionidAndId(Integer regionId, Integer id);

}

regions repository

package com.example.repository;
import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import com.example.model.Regions;

public interface RegionsRepository extends JpaRepository<Regions, Integer> {

      List<Regions> findByNameContaining(String name);

}

And finaly the controller method:

@PostMapping("/add")
    public ResponseEntity<TownDTO> createPost(@RequestBody TownDTO townDto) {

        
        // convert DTO to entity
        Towns townRequest = modelMapper.map(townDto, Towns.class);
            //System.out.println(townDto.regionid);
        //System.out.println(townRequest.getName());
        Towns town = townsrepository.save(townRequest);
        

        // convert entity to DTO
        TownDTO townResponse = modelMapper.map(town, TownDTO.class);

        return new ResponseEntity<TownDTO>(townResponse, HttpStatus.CREATED);
    }

I am able to print out townDTO.regionid and value is correct 2 in my case. But request is still null. Here is a request from postman

{
"name": "test",
"regionid": "2"

}

What am I missing right now?

Removed @jsonignore and added getters and setters to DTO

package com.example.dto;
import java.util.HashSet;
import java.util.Set;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;

@Data

public class TownDTO {
    public String name;
       public String regionid;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getRegionid() {
        return regionid;
    }
    public void setRegionid(String regionid) {
        this.regionid = regionid;
    }
    
       
}

Nothin had change. Error is the same

Bogdan Onyshenko
  • 415
  • 1
  • 6
  • 24
  • 1
    sounds like a problem in `ModelMapper` , how is `String regionid` mapped to `Region regionid`??? (i assume: not at all/very flat) Is this region(2) already persisted? calling a referenced entity same as the join column is also somewhat "unconventional"/can raise confusion. – xerx593 Jan 10 '22 at 17:37
  • 1
    What do you mean by persisted? If you mean saved in a regions table, then yes. there is a record with id=2 – Bogdan Onyshenko Jan 10 '22 at 17:40
  • 1
    Repeating what xerx593 stated - regionid : "2" is a string value, but you have Town.regionid requiring a "Regions" instance. What is the ModelMapper returning for the townRequest.regionid,? The error is stating it is null, which means you'll have to handle this string to Regions conversion yourself (you marked it as JsonIgnore), and should probably use a repository lookup to fetch the instance with the value 2 from the DB and use that instance in the created townRequest.regionsid reference. – Chris Jan 10 '22 at 20:53
  • @Chris Well thank you. I just removed a JsonIgnore from regionid and get a same error. Plus regionid is still null. How to convert it then? – Bogdan Onyshenko Jan 11 '22 at 06:42
  • Is it related to the fact that I am not using a Service layer? – Bogdan Onyshenko Jan 11 '22 at 07:07
  • 1
    Im not sure about how the mapper is setup, but am skeptical it can automatically understand and know what you want done with a String 'int' value. This isn't a Region instance. Does it work in reverse - is the regionId string populated when you expect it to be? You might be better off creating a basic mapping for this regionId foreign key in your entity, and using that in your DTO. Just mark the relationship (or the basic, which ever you prefer) as updatable=false, insertable=false, so that there is only one write able mapping for the db column. – Chris Jan 11 '22 at 16:27

1 Answers1

0

Your TownDTO contains String regionid whereas your Model class it's Region Object. So moddlemapper can't map.

//DTO
public String regionid;

//Model
private Regions regionid;
bhanuja
  • 16