0

我有兩個實體在MySQL DB中,我想實現一個雙向映射,自動保存新孩子保存一個新的父母時。保存父母和孩子的實體在同一個notnull外鍵的父母(春季JPA /休眠)

MACCHINA(父)字段:ID,馬卡

PERSONA(子)字段:ID,諾姆,macchina_id(外鍵NOT NULL)

當我保存一個新MACCHINA,我想也救新PERSONA這個JSON:

{ 
    "marca": "string", 
    "personas": [ 
    { 
     "nome": "string" 
    } 
    ] 
} 

MACCHINA實體:

@Entity 
@Table(name = "macchina") 
public class Macchina implements Serializable { 

    private static final long serialVersionUID = 1L; 

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

    @NotNull 
    @Column(name = "marca", nullable = false) 
    private String marca; 

    @OneToMany(mappedBy = "macchina", cascade = CascadeType.ALL) 
    private Set<Persona> personas = new HashSet<>(); 

    // getters and setters ... 
} 

PERSONA實體:

@Entity 
@Table(name = "persona") 
public class Persona implements Serializable { 

    private static final long serialVersionUID = 1L; 

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

    @NotNull 
    @Column(name = "nome", nullable = false) 
    private String nome; 

    @ManyToOne(optional = false) 
    @JoinColumn(name="macchina_id", referencedColumnName = "id", nullable = false) 
    private Macchina macchina; 

     // getters and setters ... 
    } 

在這種情況下,當我打電話的JPA庫法.save()的Macchina實體,我有例外:

> Caused by: 
> com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 
> Column 'macchina_id' cannot be null 

同樣在這一場景中,我嘗試在數據庫中刪除Persona表中字段「macchina_id」的NotNull約束;在這種情況下,事務被執行,但Persona表中的「macchina_id」字段爲NULL。

我發現了一個變通的數據庫(在實體和註釋)去除NOTNULL約束的「macchina_id」,並通過這種方式從父母向子女修改映射:

@OneToMany(cascade = CascadeType.ALL) 
@JoinColumn(name = "macchina_id") 
private Set<Persona> personas = new HashSet<>(); 

我刪除了「mappedBy」並添加了@JoinColumn。 以這種方式工作:Hibernate在Macchina中執行插入操作,插入到Persona中,最後更新Persona(我想寫入/更新macchina_id字段)。

我的目標是維護數據庫中字段「macchina_id」的NotNull屬性;在映射字段private Macchina macchina;(如@NotNull/nullable = false/@ManyToOne(可選= false))的子實體中保留一些屬性值,並使用Spring/Hibernate自動驗證的「macchina_id」字段同時保存這兩個實體,無需手動編寫代碼。

因此,有一種自動方式(Spring/Hibernate)先保存父項,然後保存對父項有NotNull外鍵的子項?

有什麼建議嗎?

問候,安德烈

+0

,加如果你想只保存 –

+0

告訴我們你的代碼如何保存 –

+0

在新的答案中顯示 –

回答

0

用來做保存代碼是非常簡單的:我接收來自REST的JSON成DTO,然後我的DTO映射到域對象,最後我調用該方法.save ()的JpaRepository。

@Override 
@Transactional 
public MacchinaDTO save(MacchinaDTO macchinaDTO) { 
    log.debug("Request to save Macchina : {}", macchinaDTO); 
    Macchina macchina = macchinaMapper.toEntity(macchinaDTO); 
    macchina = macchinaRepository.save(macchina); 
    return macchinaMapper.toDto(macchina); 
} 
+0

添加到您的問題 –

0

我想盡量避免手工添加MacchinaPersona。我試圖通過Spring/Hibernate來管理這個(因爲如果我從外鍵中刪除非空約束,它會起作用)。

要做到這個例子中,我使用的是該項目產生JHipster產生(如果你知道)的一個項目,它使用MapStruct映射DTO和領域:節能`Macchina`前

/** 
* Contract for a generic dto to entity mapper. 
@param <D> - DTO type parameter. 
@param <E> - Entity type parameter. 
*/ 

public interface EntityMapper <D, E> { 
    public E toEntity(D dto); 
    public D toDto(E entity); 
    public List <E> toEntity(List<D> dtoList); 
    public List <D> toDto(List<E> entityList); 
} 

/** 
* Mapper for the entity Macchina and its DTO MacchinaDTO. 
*/ 
@Mapper(componentModel = "spring", uses = {PersonaMapper.class}) 
public interface MacchinaMapper extends EntityMapper <MacchinaDTO, Macchina> { 

    default Macchina fromId(Long id) { 
     if (id == null) { 
      return null; 
     } 
     Macchina macchina = new Macchina(); 
     macchina.setId(id); 
     return macchina; 
    } 
} 

@Generated(
    value = "org.mapstruct.ap.MappingProcessor", 
    date = "2017-07-21T11:57:12+0200", 
    comments = "version: 1.1.0.Final, compiler: Eclipse JDT (IDE) 3.12.3.v20170228-1205, environment: Java 1.8.0_141 (Oracle Corporation)" 
) 
@Component 
public class MacchinaMapperImpl implements MacchinaMapper { 

    @Autowired 
    private PersonaMapper personaMapper; 

    @Override 
    public MacchinaDTO toDto(Macchina arg0) { 
     if (arg0 == null) { 
      return null; 
     } 

     MacchinaDTO macchinaDTO = new MacchinaDTO(); 

     macchinaDTO.setId(arg0.getId()); 
     macchinaDTO.setMarca(arg0.getMarca()); 
     Set<PersonaDTO> set = personaSetToPersonaDTOSet(arg0.getPersonas()); 
     if (set != null) { 
      macchinaDTO.setPersonas(set); 
     } 

     return macchinaDTO; 
    } 

    @Override 
    public List<MacchinaDTO> toDto(List<Macchina> arg0) { 
     if (arg0 == null) { 
      return null; 
     } 

     List<MacchinaDTO> list = new ArrayList<MacchinaDTO>(); 
     for (Macchina macchina : arg0) { 
      list.add(toDto(macchina)); 
     } 

     return list; 
    } 

    @Override 
    public Macchina toEntity(MacchinaDTO arg0) { 
     if (arg0 == null) { 
      return null; 
     } 

     Macchina macchina = new Macchina(); 

     macchina.setId(arg0.getId()); 
     macchina.setMarca(arg0.getMarca()); 
     Set<Persona> set = personaDTOSetToPersonaSet(arg0.getPersonas()); 
     if (set != null) { 
      macchina.setPersonas(set); 
     } 

     return macchina; 
    } 

    @Override 
    public List<Macchina> toEntity(List<MacchinaDTO> arg0) { 
     if (arg0 == null) { 
      return null; 
     } 

     List<Macchina> list = new ArrayList<Macchina>(); 
     for (MacchinaDTO macchinaDTO : arg0) { 
      list.add(toEntity(macchinaDTO)); 
     } 

     return list; 
    } 

    protected Set<PersonaDTO> personaSetToPersonaDTOSet(Set<Persona> set) { 
     if (set == null) { 
      return null; 
     } 

     Set<PersonaDTO> set_ = new HashSet<PersonaDTO>(); 
     for (Persona persona : set) { 
      set_.add(personaMapper.toDto(persona)); 
     } 

     return set_; 
    } 

    protected Set<Persona> personaDTOSetToPersonaSet(Set<PersonaDTO> set) { 
     if (set == null) { 
      return null; 
     } 

     Set<Persona> set_ = new HashSet<Persona>(); 
     for (PersonaDTO personaDTO : set) { 
      set_.add(personaMapper.toEntity(personaDTO)); 
     } 

     return set_; 
    } 
} 
+0

'我想盡量避免添加Macchina手工添加到每個角色.',因爲你沒有從視圖映射'Macchina'到'角色'你必須這樣做**手動**。或者你可以將Macchina映射到Persona ** personaDTOSetToPersonaSet **這裏也是\ –