Search code examples
javaspring-bootspring-data-jpahql

sql update one to many using spring jpa (foreign key null)


Im working with spring boot, java 11 and jpa.

I have 2 tables, entry and entry_names. I want to update both an entry, and its subsequent many to one relationship in the second table(entry_names).

The problem: Entry_id field is always null, so it creates new entries in Entry_names instead of updating them. What am i doing wrong? This is my most up-to-date code:

Tables:

+-------+
| Entry |
+-------+
| id    | pk:id
| title |
| text  |
+-------+

+-----------+
|entry_names| 
+-----------+
| id        | pk: id 
| name      | fk: entry_id -> entry(id)
| entry_id  |
+-----------+

These are the entities:

Entry:

@Entity
@Table(name="entry")
@Getter
@Setter
public class Entry {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id;
    private String title;
    private String text;
    
    @OneToMany(
            fetch = FetchType.EAGER,
            mappedBy = "entry",         
            cascade = CascadeType.ALL, 
            orphanRemoval = true)
    private Set<EntryNames> names;
}

Entry_names:

@Entity
@Table(name="entry_names")
@Getter
@Setter
public class EntryNames {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "entry_id")
    private Entry entry;

    @Column(name = "name")
    private String name;
}

Code:

@Override
@Transactional
public boolean update(EntryDto dto) {
    
    try {
        Optional<Entry> findEntry = dao.findById(entry.getId());
        if (findEntry.isPresent()) {
            Entry entry = findEntry.get();
            
            Set<EntryNames> entryNames = new HashSet<>();
            entry.getName().forEach(entryNames -> entryNames.add(new EntryName(entryName)));
            entryNames.forEach(entryName -> entryName.setId(entry.getId()));
            entry.setName(entryNames);
            dao.save(entry);
            return true;
        }
        return false;
    } catch (Exception exception) {
        logger.error("ERROR: {}", exception.getMessage());
        return false;
    }
}   

(edited to remove assignment, still same problem)


Solution

  • You are setting names with new HashSet<>(); which will overwrite the values.

    Change to:

      private Set<EntryNames> names ;
    

    Aslo add this in update method

     entrynames.setEntry(entry)