gpt4 book ai didi

java - Hibernate - 通过一次保存映射三个表

转载 作者:行者123 更新时间:2023-12-02 01:22:58 26 4
gpt4 key购买 nike

我正在尝试创建一个项目,该项目将使用 Hibernate 将对象存储到数据库中。

如果我只是插入(保存)一个不包含与另一个表的映射的对象,则一切正常。但是,我有一个情况,三个表之间存在连接。这些表是 Asset、MonetaryValue 和CurrencyType(见下文)。

插入 Assets 时,必须(由用户)提供货币值类型以及货币类型。 Asset 与MonetaryValueType 保持OneToOne 关系,MonetaryValueType 与CurrencyType Table 保持OneToOne 关系。更具体地说,您将在下面找到数据库表。

Asset(asset_id,ownerIID,valueID,samID), where valueID is the foreign key to the MonetaryValueType Table (OneToOne undirectional mapping)

MonetaryValueType(mvID, mValue,currencyId), where currencyID is the foreign key to the CurrencyType Table (OneToOne undirectional mapping)

CurrencyType(currencyID,currField,currValue,currSymbol).

问题是,每次我创建 Assets 对象并调用 Assets 服务来保存元素时,Hibernate 要么创建一个选择查询,尝试从我从未定义的数据库表中进行选择,要么插入货币字段列名错误(即currency_field而不是currField等)

我尝试过使用所有 Cascade 类型,但似乎没有任何效果。

Asset.java

@Entity
@Table(name="asset")
public class Asset implements java.io.Serializable{

@Id
@Column(name="assetID", unique = true, nullable = false)
private long assetID;

@Column(name="ownerID")
private long ownerID;

@OneToOne
@JoinColumn(name="valueID")
private MonetaryValueType monetaryValueType;

@Column(name="samID")
private long samID;
------------Constructor, Getters , Setters-----
MonetaryValueType.java

@Entity
@Table(name="monetaryvaluetype")
public class MonetaryValueType{

@Id
@Column(name="mvID",nullable = false,unique = true)
private Long id;

@Column(name="mValue")
private double mValue;

@OneToOne
@JoinColumn(name="currencyId")
private CurrencyType currency;
------------Constructor, Getters , Setters-----


CurrencyType.java

@Entity
@Table(name="currencytype")
public class CurrencyType implements java.io.Serializable {

@Id
@Column(name="currencyID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int currencyID;

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

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

@Column(name="currSymbol")
private String currSymbol;
------------Constructor, Getters , Setters-----

每个实体都拥有自己的 DAO、DAOImpl、Service 和 ServiceImpl 类。例如,对于 Assets 类别,可以在下面找到 DAOImpl 和 ServiceImpl:

AssetDAOImpl.java

@Repository
public class AssetDAOImpl implements AssetDAO{
private Logger logger = LoggerFactory.getLogger(this.getClass());
//entity manager field
@Autowired
private EntityManager entityManager;




@Override
public List<Asset> findAll() {
Session currentSession = entityManager.unwrap(Session.class);
//create a query
Query theQuery =
currentSession.createQuery("from asset",Asset.class);
//execute query and get result list
List<Asset> aModelElements = theQuery.getResultList();
//return the results
return aModelElements;
}

@Override
public Asset findById(int theId) {
return null;
}

@Override
public Asset insert(Asset assetElement) {

//Session currentSession = entityManager.unwrap(Session.class);
boolean success = false;
try {

entityManager.persist(assetElement);
logger.info("Asset -> {}", assetElement);
return assetElement;
}
catch(Exception e){
e.printStackTrace();
}
return null;
}

AssetServiceImpl.java

@Service
public class AssetServiceImpl implements AssetService {

private Logger logger = LoggerFactory.getLogger(this.getClass());
private AssetDAO assetDAO;

@Autowired
public AssetServiceImpl(AssetDAO theAssetDAO){
assetDAO=theAssetDAO;
}

@Override
@Transactional
public List<Asset> findAll() {

return assetDAO.findAll();
}

@Override
@Transactional
public Asset findById(int theId) {
return assetDAO.findById(theId);
}

@Override
@Transactional
public Asset insert(Asset theAsset) {
assetDAO.insert(theAsset);
return theAsset;

}
...

我用来填充 Assets 类别(及其所有子类别)的类是:

 UniqueIDGenerator uniqueIDGenerator = new UniqueIDGenerator();
CurrencyType currencyType = new CurrencyType();
Asset asset = new Asset();
MonetaryValueType monetaryValueType = new MonetaryValueType();

currencyType.setCurrValue(ctx.value().monetaryValueType().currency().CurrencyType().getText());
currencyType.setCurrSymbol("currency");

monetaryValueType.setId(uniqueIDGenerator.nextId());
monetaryValueType.setmValue(Double.parseDouble(ctx.value().monetaryValueType().mValue().getText()));
monetaryValueType.setCurrency(currencyType);

asset.setMonetaryValueType(monetaryValueType);
asset.setAssetID(uniqueIDGenerator.nextId());
asset.setOwner(uniqueIDGenerator.nextId());
asset.setSamID(uniqueIDGenerator.nextId());
assetService.insert(asset);

每当我调用上述类时,都会收到以下错误:

Hibernate: 
insert
into
element1
(datefrom, dateto, description, name, statusid, samid)
values
(?, ?, ?, ?, ?, ?)
2019-08-05 20:19:00 INFO MyClass:63 - the result is:true
Hibernate:
select
monetaryva_.mvid,
monetaryva_.currency_id as currency3_57_,
monetaryva_.m_value as m_value2_57_
from
monetaryvaluetype monetaryva_
where
monetaryva_.mvid=?
2019-08-05 20:19:01.084 WARN 56712 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1054, SQLState: 42S22
2019-08-05 20:19:01.084 ERROR 56712 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : Unknown column 'monetaryva_.currency_id' in 'field list'

如您所见,即使我使用了 @Column 注释,hibernate 创建的列(currency_id 而不是currencyID)也不符合我的数据库表。

最佳答案

在 application.properties 文件中使用以下两行

spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

关于java - Hibernate - 通过一次保存映射三个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57363837/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com