簡體   English   中英

OneToMany 返回 null 響應來自目標實體的 JoinColumn,即使值已插入數據庫 - Spring 啟動 JPA

[英]OneToMany returns null in response on JoinColumn from target Entity even though value was inserted in database - Spring boot JPA

我有兩個與@OneToMany 結合的模型/實體,將 PK 從一個表保存到另一個表作為外鍵。 我也想獲得新更新的外鍵作為響應。

這是我的代碼

類別型號

@Data
@AllArgsConstructor
@Getter
@Builder
public class CategoryModel {
    
    public String categoryName;
    public List<BeveragesModel> beverages;
    
}

飲料模型

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class BeveragesModel {
    
    public Integer categoryID;
    public String name;
    public double price;
    
    
}

模型的實體當前具有與模型相同的字段

飲料實體

@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "BEVERAGES")
@ToString
@Builder
public class BeveragesEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    public Integer id;
    @Column(name = "CATEGORY_ID")
    public Integer categoryId;
    @Column(name = "NAME")
    public String name;
    @Column(name = "PRICE")
    public double price;
    
    @ManyToOne
    public void setCategoryId(Integer id) {
        this.categoryId=id;
    }
    
}

類別實體

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "CATEGORY")
public class CategoryEntity {

    // TO DO kako dobiti na front zapis iz BEVERAGES tablice za CATEGORY_ID kojeg spremam...
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    public Integer id;
    @Column(name = "CATEGORY_NAME")
    public String categoryName;
    @Column(name = "BEVERAGES")
    @OneToMany(targetEntity = BeveragesEntity.class, cascade = CascadeType.ALL)
    @JoinColumn(name = "CATEGORY_ID", referencedColumnName = "id")
    List<BeveragesEntity> beverages;
}

Controller 只是調用服務

@RestController
@CrossOrigin(origins = "*")
public class CategoryController {

    
    @Autowired
    CategoryService categoryService;

    @RequestMapping(path = "/addCategory", method = RequestMethod.PUT)
    public CategoryEntity addCategory(@RequestBody CategoryRequest request) {
        return categoryService.addCategory(request);
    }
    
}

CategoryService 目前正在將對象從模型重建為實體

@Service
public class CategoryServiceImpl implements CategoryService {
    
    @Autowired
    CategoryRepository categoryRepository;
    
    public CategoryEntity addCategory(CategoryRequest request) {
        
        List<BeveragesModel> beveragesModel = request.getCategory().getBeverages();
        List<BeveragesEntity> beveragesEnties = new ArrayList<>();
        if(!beveragesModel.isEmpty()) {
            for(BeveragesModel model : beveragesModel)  {
                BeveragesEntity beveragesEntity = BeveragesEntity.builder()
                        .name(model.getName())
                        .price(model.getPrice())
                        .build();
                beveragesEnties.add(beveragesEntity);
                
            }
        }
        
        CategoryEntity categoryEntity = CategoryEntity.builder()
                .categoryName(request.getCategory().getCategoryName())
                .beverages(beveragesEnties)
                .build();
        
        return categoryRepository.save(categoryEntity);
    }

請求是

    { 
    "category" : {
        "categoryName": "Alkoholna pića",
        "beverages": [
            {
                "name":"Ozujsko",
                "price":16.0
            },
            {
                "name":"Stella Artois",
                "price":18.0
            }
        ]
    }
}

這是回應

    {
    "id": 1,
    "categoryName": "Alkoholna pića",
    "beverages": [
        {
            "id": 1,
            "categoryId": null,
            "name": "Ozujsko",
            "price": 16.0
        },
        {
            "id": 2,
            "categoryId": null,
            "name": "Stella Artois",
            "price": 18.0
        }
    ]
}

我想從 objeck 飲料中獲取 categoryId 作為后端的響應,但作為響應我得到 null。 Howerver 在我的 H2 數據庫中的 BEVERAGES 表中,我可以看到 categoryId 與 CATEGORY 表中的 ID 正確保存(在這種情況下,這兩條記錄的 CATEGORY_ID = 1)

如果有人能幫助我,那就太好了...

您的問題源於 BeverageEntity 具有 categoryId 而不是 CategoryEntity。 正常的雙向關系如下:

    // CategoryEntity
    @OneToMany(cascade = CascadeType.ALL)
    List<BeveragesEntity> beverages;

    // BeverageEntity
    @ManyToOne
    @JoinColumn(name = "CATEGORY_ID")
    private CategoryEntity category;

在保存之前,除了將飲料集合設置為類別之外,您還應該確保每種飲料都有一個類別集。 這是對您的服務方法的一個調整,評論突出了這一點。

    public CategoryEntity addCategory(CategoryRequest request) {

        List<BeveragesModel> beveragesModel = request.getCategory().getBeverages();
        
        CategoryEntity categoryEntity = CategoryEntity.builder()
                .categoryName(request.getCategory().getCategoryName())
                .build();

        List<BeveragesEntity> beveragesEnties = new ArrayList<>();
        if (!beveragesModel.isEmpty()) {
            for (BeveragesModel model : beveragesModel) {
                BeveragesEntity beveragesEntity = BeveragesEntity.builder()
                        .name(model.getName())
                        .price(model.getPrice())
                        .category(categoryEntity) // set category in each beverage
                        .build();
                beveragesEnties.add(beveragesEntity);
            }
        }

        categoryEntity.setBeverages(beveragesEnties); // set beverages in category

        return categoryRepository.save(categoryEntity);
    }

當您從 controller 返回身份本身時,CategoryEntity 和 BeveragesEntity 之間存在循環依賴關系,因此您需要防止這種情況發生。 在您的情況下,您希望在飲料 json 對象中包含 categoryId,因此您可以通過將以下注釋添加到 BeveragesEntity 中的類別字段來執行此操作。 我不確定客戶端如何處理返回的數據,但包括 categoryId 只是復制已經在類別 json object 中的 id

    @JsonProperty("categoryId")
    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
    @JsonIdentityReference(alwaysAsId = true)
    @ManyToOne
    @JoinColumn(name = "CATEGORY_ID")
    private CategoryEntity category;

我實現了您的代碼並在上面進行了上述更改,從 controller 返回的響應如下

{
    "id": 1,
    "categoryName": "Alkoholna pica",
    "beverages": [
        {
            "id": 2,
            "name": "Ozujsko",
            "price": 16.0,
            "categoryId": 1
        },
        {
            "id": 3,
            "name": "Stella Artois",
            "price": 18.0,
            "categoryId": 1
        }
    ]
}

最后,我會避免將 Lombok 與 Entities 一起使用,特別是因為 @Data 將自動生成 equals 和 hashcode 方法,並且您希望確保它們在您使用數據庫生成的標識符文章時正確實現這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM