Java Hibernate—使用单个存储映射三个表

Java Hibernate—使用单个存储映射三个表,java,hibernate,spring-boot,spring-data-jpa,Java,Hibernate,Spring Boot,Spring Data Jpa,我正在尝试创建一个项目,该项目将使用Hibernate将对象存储到数据库中 如果我只是插入(保存)一个不包含与另一个表的映射的对象,那么一切都可以正常工作。然而,我有一个例子,三个表之间有一个连接。这些表格包括资产、货币价值和货币类型(见下文) 插入资产时,必须(由用户)随货币类型一起提供monetaryValueType。资产与MonetaryValueType保持一个OneToOne关系,MonetaryValueType与CurrencyType表保持一个OneToOne关系。 更具体地说

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

如果我只是插入(保存)一个不包含与另一个表的映射的对象,那么一切都可以正常工作。然而,我有一个例子,三个表之间有一个连接。这些表格包括资产、货币价值和货币类型(见下文)

插入资产时,必须(由用户)随货币类型一起提供monetaryValueType。资产与MonetaryValueType保持一个OneToOne关系,MonetaryValueType与CurrencyType表保持一个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).
问题是,每次我创建asset对象并调用asset服务来保存元素时,Hibernate要么创建一个选择查询,尝试从我从未定义过的数据库表中进行选择,要么在currency字段中插入错误的列名(即currency_字段而不是Current字段等)

我尝试过使用所有的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-----
每个实体都拥有自己的DAO、DAOImpl、Service和ServiceImpl类。例如,对于资产类别,可以在下面找到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;
    }

无论何时调用上述类,都会出现以下错误:

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'

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

在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

在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

如果这些实体之间的关系都是一对一的,那么三个单独的实体和三个单独的表到底有什么意义?并不是说这样把他们分开是不对的,但它增加了复杂性并降低了效率,但没有提供任何对我来说显而易见的抵消效益。@JohnBollinger,因为还有其他关系也使用这些表/如果这些实体之间的关系都是一对一的,那么三个单独的实体和三个单独的实体到底有什么意义桌子?并不是说这样拆分它们一定是错误的,但这增加了复杂性,降低了效率,却没有提供任何明显的抵消好处。@JohnBollinger,因为还有其他关系也使用这些表/Wow!这实际上解决了问题!非常感谢你!哇!这实际上解决了问题!非常感谢你!
 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'
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl