我想做以下作業:
使用JPA將CityHistory插入資料庫。
使用JPA將CityHistory插入資料庫中。 第一次沒有資料,所以將插入一個新的城市。(它作業正常) 城市表中的(IDENTIFICATION)是一個唯一的欄位。
我想實作的是,當我再次插入同一個城市時,我將重新使用現有的欄位,而不是試圖創建一個新的欄位(標識將像一個城市的唯一名稱)。
那么我如何使用JPA或Hibernate來實作這個目標呢?
@Entity
public class CityHistory extends History implements Serializable{
@Id
@Column(name = "KEY_CITY_HISTORY", nullable = false, precision = 19)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "CITY_ID", nullable = false, foreignKey = @ForeignKey(name = "FK_CITY_ID"))
private City cityId;
@Column(name = "CITY_NAME", nullable = false)
private String cityName;
}
@Entity
public class City implements Serializable {
@Id
@Column(name = "KEY_CITY", nullable = false, precision = 19)
private Long id;
@Column(name = "IDENTIFICATION", nullable = false, unique = true)
private String identification;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "MUNICIPALITY_ID", foreignKey = @ForeignKey(name = "FK_MUNICIPALITY_ID))
private Municipality municipalityId;
}
UPDATE 這里是我如何將資料寫入資料庫的。 它是一個Spring Batch itemWriter
。@Component
public class InfoItemWriter implements ItemWriter<Object> {
@Autowired
private CityHistoryRepository cityHistoryRepository;
@Override
public void write(List<? extends Object> items) throws Exception{
if (items.size() > 0 && items.get(0) instanceof CityHistory) {
cityHistoryRepository.saveAll((List<? extends CityHistory>)專案)。)
}
}
uj5u.com熱心網友回復:
首先感謝所有試圖提供幫助的人!
閱讀@Benjamin Maurer提供的資源。
閱讀@Benjamin Maurer提供的資源:
我認為你不希望在ManyToOne方面進行級聯,請參閱One-To-Many
最常見的父-子關聯包括一對多和多對一的關系,其中級聯只對一對多的一方有用
由于我的關系是ManyToOne,所以使用級聯真的沒有用,也不能滿足我的需求。
我使用了一種不同的方法來達到目標。我創建了一個服務,它驗證了一個城市的存在,如果它不存在,就添加一個新的城市。
@Service
public class CityHistoryServiceImpl implementsCityHistoryService {
@Autowired
CityRepository cityRepository;
@Autowired[/span
CityHistoryRepository cityHistoryRepository;
@Override[/span
public Optional<CityHistory> addCityHistory(City city, String cityName, ...) {
if (city != null && cityName != null) {
City city1 = addCityIfNotExist(city)。
CityHistory cityHistory = new CityHistory() 。
cityHistory.setCityId(city1);
cityHistory.setCityName(cityName);
cityHistoryRepository.save(cityHistory)。
return Optional.of(cityHistory)。
}
return Optional.empty()。
} ....
private City addCityIfNotExist(City city) {
City city1 = cityRepository.findFirstByBagId(city.getBagId())。
if (city1 == null) {
city1 = cityRepository.save(city)。
}
return city1;
}
uj5u.com熱心網友回復:
Hibernate將使用City的@Id屬性來確定它是否是新的。當它是null時,Hibernate不可能知道一個類似的條目已經存在。
因此,你需要先執行一個查詢來找到每個城市:
for (var history : histories) {
var cities = em.createQuery("select city from City city where city.identification = ?1"/span>, City.class)
.setParameter(1, history.getCityId().getIdentification()
.getResultList()。
if (!cities.isEmpty() ) {
history.setCityId(cities.get(0))。
}
em.persist(history)。
}
如果你使用Hibernate并且City.identification是唯一的并且總是非空的,你可以把它作為NaturalID:
在城市:
@NaturalId
private字串標識。
然后:
for (var history : histories) {
var city = em.unwrap(Session.class)
.byNaturalId(City.class)
.using("identification", history.getCityId().getIdentification()
.getReference()。
if (city != null) {
history.setCityId(city)。
}
em.persist(history)。
}
但是如果你有City.id設定,即不空,你可以使用EntityManager.merge來獲得一個被管理的物體:
for (var history : histories) {
City city = history.getCityId()。
if (city.getId() != null) {
city = em.merge(city);
history.setCityId(city)。
}
em.persist(history)。
}
還有一句話。我們不是在關系域,而是在映射物件圖。所以稱你的欄位為cityId和municipalityId可以說是錯誤的--甚至在型別上也是如此。City cityId。
它們不只是普通的識別符號,而是完全成熟的物件。City城市.
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/309822.html
標籤:
