JPA的OneToOne映射不会更新子对象,而是会插入一个新对象。

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

JPA OneToOne Mapping doesn't update child but instead inserts a new one

问题

RuleEntity

@Entity
@Table(name = "rules")
public class RuleEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer RuleId;

    @Column(name = "rule_expression")
    private String RuleExpression;

    @Column(name = "rule_frequncy")
    private Integer RuleFrequency;

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "alert_id")
    private AlertEntity alertEntity;
}

AlertEntity

@Entity
@Table(name = "alerts")
public class AlertEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "alert_id")
    private Integer alertId;

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

RuleRepository

@Repository
@Transactional
public interface RuleRepository extends JpaRepository<RuleEntity, Integer> {}

Code

RuleEntity ruleEntity = new RuleEntity();
AlertEntity alertEntity = new AlertEntity();
alertEntity.setAlertAction(data.getAlertAction());
ruleEntity.setAlertEntity(alertEntity);
if (newRule) ruleEntity.setRuleId(data.getRuleId());
ruleEntity.setRuleExpression(data.getRuleExpression());
ruleEntity.setRuleFrequency(data.getRuleFrequency());
ruleRepository.save(ruleEntity);

当我使用 ruleRepository.save(ruleEntity) 而没有提供 ruleEntity.RuleId 时,会插入新的规则和警报,警报的主键会在 rules 表的 alert_id 列中提供。

如果我提供了 ruleEntity.RuleId 并保存了 ruleEntity,那么与 RuleId 相关联的数据会被更新,但是在 alerts 表中会插入新行。

我想要的是通过使用 rules 表中的 id 来更新现有警报。如何实现这一点?

英文:

RuleEntity

@Entity
@Table(name = &quot;rules&quot;)
public class RuleEntity {
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Integer RuleId;
	
	@Column(name = &quot;rule_expression&quot;)
	private String RuleExpression;
	
	@Column(name = &quot;rule_frequncy&quot;)
	private Integer RuleFrequency;

	@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
	@JoinColumn(name=&quot;alert_id&quot;)
	private AlertEntity alertEntity;
}

AlertEntity

@Entity
@Table(name = &quot;alerts&quot;)
public class AlertEntity {
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name = &quot;alert_id&quot;)
	private Integer alertId;

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

RuleRepository

@Repository
@Transactional
public interface RuleRepository extends JpaRepository&lt;RuleEntity, Integer&gt;{}

Code

RuleEntity ruleEntity= new RuleEntity();
AlertEntity alertEntity = new AlertEntity();
alertEntity.setAlertAction(data.getAlertAction());
ruleEntity.setAlertEntity(alertEntity);
if(newRule) ruleEntity.setRuleId(data.getRuleId());
ruleEntity.setRuleExpression(data.getRuleExpression());
ruleEntity.setRuleFrequency(data.getRuleFrequency());
ruleRepository.save(ruleEntity);

When I use ruleRepository.save(ruleEntity) and don't provide ruleEntity.RuleId a new rule and alert are inserted and alert primary key is provided in alert_id column of the rules table.

If I provide ruleEntity.RuleId and save ruleEntity then data associated with RuleId gets updated but new row gets inserted in alerts table.

What I want is to update existing alert by using id from rules table. How to achieve this?

答案1

得分: 0

代替这个逻辑:

if(newRule) ruleEntity.setRuleId(data.getRuleId());

你可以尝试获取可能已经存在的规则,类似这样:

RuleEntity ruleEntity;
if(newRule) {
    ruleEntity = new RuleEntity();
} else {
    ruleEntity = ruleRepository.findById(data.getRuleId());
}

现在,根据 ruleEntity 是否已经有 alertEntity,你只需在保存之前获取 getAlertEntity() 并进行更新。如果没有,你只需创建一个新的,并在保存之前使用来自 data 的值设置 setAlertEntity(aNewAlertEntity)

请注意,这只是一个简化的示例,你需要注意可能的 Optional 检查等,但基本思路应该是清楚的。

英文:

Instead of this logic:

if(newRule) ruleEntity.setRuleId(data.getRuleId());

you should try to fetch the possibly existing rule, something like:

RuleEntity ruleEntity;
if(newRule) {
    ruleEntity = new RuleEntity();
} else {
    ruleEntity = ruleRepository.findById(data.getRuleId())
}

Now depending on if ruleEntity has alertEntity already you just getAlertEntity() and update it before saving. If not you just create a new one and then setAlertEntity(aNewAlertEntity) with values from data before saving.

Note that this is simplified example and you need to take care of possible Optional chacks and so on but the basic idea should be clear.

huangapple
  • 本文由 发表于 2020年10月14日 16:18:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/64349270.html
匿名

发表评论

匿名网友

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

确定