简体   繁体   中英

Setting OneToOne relationship in entity with inheritance

I created abstract class Entity (I want to create different types of shapes):

@Entity
@Inheritance(strategy = TABLE_PER_CLASS)
@Getter
@Setter
@NoArgsConstructor
public abstract class ShapeEntity {
    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    private String id;
    @OneToOne
    private ShapeDetailsEntity shapeDetailsEntity;

    public abstract double getArea();

    public abstract double getPerimeter();
}

and I want to every add to every entity table with details:

@Entity
@Getter
@Setter
@Table(name = "shape_details")
@AllArgsConstructor
public class ShapeDetailsEntity {
    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    private String id;
    ...
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "shapeDetailsEntity", fetch = FetchType.LAZY)
    private ShapeEntity shapeEntity;

The logic of creating entites is in service:

public class ShapeService {
    public ShapeEntity createShape(ShapeType type, List<Double> parameters) {
        switch (type) {
            case CIRCLE:
                return circleEntityRepository.saveAndFlush(new CircleEntity(parameters));
            case SQUARE:
                return squareEntityRepository.saveAndFlush(new SquareEntity(parameters));
            case RECTANGLE:
                return rectangleEntityRepository.saveAndFlush(new RectangleEntity(parameters));
            default:
                throw new IllegalArgumentException();
        }
    }

and now for tests in controller I would like to create new entity - in comments I put response in console:

@PostMapping
public ResponseEntity<String> post(@Valid @RequestBody ShapeRequestModel shapeRequestModel) {
    ShapeEntity shapeEntity = shapeService.createShape(ShapeType.valueOf(shapeRequestModel.getType()), shapeRequestModel.getParameters());
    ShapeDetailsEntity shapeDetailsEntity = shapeService.createShapeDetails(shapeEntity);
    System.out.println(shapeDetailsEntity.getShapeEntity().toString()); // -> CircleEntity{radius=4.5}
    System.out.println(shapeDetailsEntity); // -> ShapeDetailsEntity{all details...}
    System.out.println(shapeEntity.getShapeDetailsEntity().toString()); // -> java.lang.NullPointerException: null

    return new ResponseEntity<>(shapeEntity.toString(), HttpStatus.CREATED);
}

in shapeService.createShapeDetails(shapeEntity) looks like:

 public ShapeDetailsEntity createShapeDetails(ShapeEntity shapeEntity) {
    ShapeDetailsEntity shapeDetailsEntity = new ShapeDetailsEntity();
    shapeDetailsEntity.setShapeEntity(shapeEntity);
    return shapeDetailsEntityRepository.saveAndFlush(shapeDetailsEntity);
}

How should I do it correctly to not getting null in shapeEntity.getShapeDetailsEntity().toString()) ? In database place when should be id of shapeDetailsEntity I am getting null.

The ShapeEntity you are creating has no ShapeDetailsEntity assigned ie the field is null, so that's why you get a NPE. If you don't want that, you have to assign an object to that field.

IMO, this shapeService.createShapeDetails(shapeEntity); code shouldn't be necessary. Your ShapeService.createShape method should assign a ShapeDetailsEntity object to the field.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM