使用Spring JPA更新一对多关系(外键为空)

huangapple go评论82阅读模式
英文:

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

问题

使用 Spring BootJava 11JPA 进行开发。

我有两个表,分别是 entryentry_names。我想要更新 entry 表中的一条记录以及其在 entry_names 表中的相关的多对一关系。

问题:
entry_id 字段始终为 null,因此它在 entry_names 表中创建新的条目,而不是更新它们。我做错了什么?以下是我最新的代码:

表结构:

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

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

这是实体类的定义:

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;
}

代码:

@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;
    }
}

(已编辑以删除分配,问题仍然存在)

英文:

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 -&gt; entry(id)
| entry_id  |
+-----------+

These are the entities:

Entry:

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

Entry_names:

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

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

    @Column(name = &quot;name&quot;)
    private String name;
}

Code:

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

(edited to remove assignment, still same problem)

答案1

得分: 1

你正在使用 new HashSet<>(); 来设置名称,这将覆盖这些值。

更改为:

private Set<EntryNames> names;

同时在更新方法中添加以下内容:

entrynames.setEntry(entry);
英文:

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

Change to:

  private Set&lt;EntryNames&gt; names ;

Aslo add this in update method

 entrynames.setEntry(entry)

huangapple
  • 本文由 发表于 2020年8月29日 02:08:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/63638914.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定