【问题标题】:Hibernate update entity best practiceHibernate 更新实体最佳实践
【发布时间】:2013-09-20 10:28:59
【问题描述】:

我正在尝试通过修改其子实体(代理)之一来更新实体(客户端),但存储库保存方法的行为与创建方法不同。

当我通过提供新的代理 ID 更新客户端时,代理未加载。

请有人解释一下为什么以及如何使这成为可能吗?

实体客户端:

@Entity
@Table(name = "client")
public class ClientEntity extends Serializable{

    private static final long serialVersionUID = -7451447955767820762L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    private int reference;

    @ManyToOne
    @JoinColumn(name = "agence_id")
    private AgenceEntity agence;

    // getter/setter
}

实体代理:

@Entity
@Table(name = "agence")
public class AgenceEntity extends AbstractGenericEntity {

    private static final long serialVersionUID = -3674920581185152947L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    private int id;

    @Column(nullable = false, length = 100)
    private String name;

    // getter/setter
}

表代理:

Id     |  Name
  1    |    name1
  2    |    name2

表客户端:

Reference    |   agence_id
  1          |     1

创建客户端:OK

Agence agence = new Agence();
agence.setId(1); // load agence #1

Client client = new Client();
client.setAgence(agence);

client = clientRepository.save(client);
System.out.println(client.getReference); // print '2'
System.out.println(client.getAgence().getName()); // print 'name1'

更新客户端:NOK

Client client = clientRepository.findOne(1); // load client #1
Agence agence = new Agence();
agence.setId(2);
client.setAgence(agence); // update agence with agence #2
client = clientRepository.save(client);
System.out.println(client.getReference); // print '1'
System.out.println(client.getAgence().getName()); // print **NULL** !!!!

【问题讨论】:

    标签: java hibernate spring-data-jpa


    【解决方案1】:

    您没有在“NOK”代码 sn-p 中设置 Agence 上的名称,因此它将打印 null。

    此外,您的主键 (id) 使用 GeneratedValue 进行注释,因此您永远不应调用 setId - 它是为您生成的,更改会导致不可预知的结果。

    【讨论】:

    • 代理已存储在数据库中。我只想将客户端 1 链接到代理 2。我知道我可以读取代理 2,然后在保存操作之前将其放入客户端 1,这会起作用,但我认为这是一个不必要的读取操作,但也许我'我错了。
    • 你确实需要先阅读它——然后你提出了一个关于阅读的有效观点。为了解决这个问题,hibernate 使用了“代理”的概念,这样当它读入对象时,它只读入一个代理而不实际访问数据库。它会创建一个 shell,其中包含您要求的主键,但实际上并没有这些值。这样您就可以在不进行读取的情况下添加对象。
    • 我不明白。我可以提供一个代码示例来说明这一点吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多