简体   繁体   English

无法确定以下类型:com.packt.cardatabase.domain.Owner,在表:car上,用于列:[org.hibernate.mapping.Column(owner)]

[英]Could not determine type for: com.packt.cardatabase.domain.Owner, at table: car, for columns: [org.hibernate.mapping.Column(owner)]

I am learning Spring and Hibernate through a book, and there is an optional exercise to create a Many to Many relationship by using Hibernate. 我正在通过一本书学习Spring和Hibernate,并且有一个可选的练习,可以使用Hibernate创建多对多关系。 Unfortunately the author did not make the optional example available on GitHub and I am lost in debugging something I am new to. 不幸的是,作者没有在GitHub上提供可选示例,并且我在调试新手时迷失了方向。

Here is the parts of the code, it works as a One to Many relationship between the Owner and Car tables, but fails as Many to Many with the above error in the title. 这是代码的各个部分,它作为Owner和Car表之间的一对多关系起作用,但由于标题中的上述错误而与多对多关系失败。 There are a few files involved but I posted the pic of the Eclipse file structure. 其中涉及一些文件,但我发布了Eclipse文件结构的图片。

cardatabase/pom file: cardatabase / POM文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"    
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0     
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<!-- Maven uses this POM file to determine dependencies -->

<groupId>com.packt</groupId>
<artifactId>cardatabase</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>cardatabase</name>
<description>Demo project for Spring Boot</description>


<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version> 2.0.4.RELEASE </version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>


    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId> spring-boot-starter-data-jpa</artifactId>
        <version> 2.0.4.RELEASE</version><!--$NO-MVN-MAN-VER$-->
    </dependency>       

    <!-- This is the dependency for the MariaDB program -->
    <dependency>
         <groupId>org.mariadb.jdbc</groupId>
         <artifactId>mariadb-java-client</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

</project>

application.properties: application.properties:

logging.level.root = INFO
spring.jpa.show-sql=true

spring.datasource.url=jdbc:mariadb://localhost:3306/cardb
spring.datasource.username=root
spring.datasource.password=nesatis
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver

spring.jpa.generate-ddl=true
spring.jpa.generate.ddl-auto=create-drop

CardatabaseApplication.java CardatabaseApplication.java

package com.packt.cardatabase;

import org.springframework.beans.factory.annotation.Autowired;//This enables dependency injection
//These next four lines are for the commandlinerunner which allows code to run before the application has fully started.
 import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import com.packt.cardatabase.domain.Car;
import com.packt.cardatabase.domain.CarRepository;
import com.packt.cardatabase.domain.Owner;
import com.packt.cardatabase.domain.OwnerRepository;


@SpringBootApplication //Enables spring boot automatic configuration
public class CardatabaseApplication 
{
@Autowired //This is used to enable dependency injection
private CarRepository repository;

@Autowired //Inject ownerrepository into the main class
private OwnerRepository orepository;

public static void main(String[] args) 
{
    //After adding this comment the application is restarted.
    SpringApplication.run(CardatabaseApplication.class, args);
}

@Bean
CommandLineRunner runner() {
    return args ->{
        Owner owner1 = new Owner("John", "Johnson");
        Owner owner2 = new Owner("Mary", "Johnson");
        orepository.save(owner1);
        orepository.save(owner2);

        // Enter Car data here. This data must fit the Car constructor String X4 int X2
        // Methods such as save are a part of the CRUD 
        repository.save(new Car("Ford", "Mustang", "Red" , "ADF-1121", 2017, 59000, owner1));
        repository.save(new Car("Nissan", "Leaf", "White", "SSJ-3002", 2014, 29000, owner2));
        repository.save(new Car("Toyota", "Prius", "Silver", "KKO-0212", 2018, 39000, owner2));
        repository.save(new Car("Honda", "Accord", "White", "AH46505", 2014, 25000, owner1));

    };
}
}

Car.java 汽车.java

package com.packt.cardatabase.domain;


import java.util.Set; //Imported to be able to use the Set method.

//Note this relies on the dependency for the persistence package in the pom.xml file
//That  dependency must be there in order for the class to see this.
import javax.persistence.*;      //This includes the Id, GeneratedValue and GeneratedType class used below.

@Entity
public class Car 
{

@Id //The primary key is defined by using the @Id annotation
@GeneratedValue(strategy=GenerationType.AUTO) //defines that the ID # is automatically generated by the database
private long id;
private String brand, model, color, registerNumber;
private int year, price;
private Owner owner;

/*
//The following two lines define a many to one relationship from car to owner
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "owner")
*/

    // If you want to use some other naming convention, use the @Column annotation
    // This will let you also define the columns length and whether the column is nullable

    /* example:
    @Column(name="desc", nullable=false, length=512)
    private String description;
    */

        public Car(String brand, String model, String color, String registerNumber, int year, int price, Owner owner) 
{
    //This is an auto-genreated constructor
    super();
    this.brand = brand;
    this.model = model;
    this.color = color;
    this.registerNumber = registerNumber;
    this.year = year;
    this.price = price;
    this.owner = owner;
}

    //The following four lines create a many to many relationship in the     cars/owners tables
    @ManyToMany(mappedBy =  "cars")
    private Set<Owner> owners;
    public Set<Owner> getOwners(){return owners;}
    public void setOwners(Set<Owner> owners) {this.owners = owners;}


public Owner getOwner() {
    return owner;
}


public void setOwner(Owner owner) {
    this.owner = owner;
}



//The following are all auto-genreated getters and setters
public String getBrand() {
    return brand;
}

public void setBrand(String brand) {
    this.brand = brand;
}

public String getModel() {
    return model;
}

public void setModel(String model) {
    this.model = model;
}

public String getColor() {
    return color;
}

public void setColor(String color) {
    this.color = color;
}

public String getRegisterNumber() {
    return registerNumber;
}

public void setRegisterNumber(String registerNumber) {
    this.registerNumber = registerNumber;
}

public int getYear() {
    return year;
}

public void setYear(int year) {
    this.year = year;
}

public int getPrice() {
    return price;
}

public void setPrice(int price) {
    this.price = price;
}
}

CarRepository.java CarRepository.java

package com.packt.cardatabase.domain;

import java.util.List; //allows the list keyword

import org.springframework.data.jpa.repository.Query;//Allows the use of the Query annotation
import org.springframework.data.repository.CrudRepository;


public interface CarRepository extends CrudRepository<Car, Long> 
{

//The following are all custom queries:

//Fetch Cars by color
List<Car> findByColor(String color);
//Fetch Cars by year
List<Car> findByYear(int year);

//Fetch Cars by brand and model
List<Car> findByBrandAndModel(String Brand, String Model);

//Fetch cars by brand using SQL using the @Query annotation.
//Remember to include the Query class in the imports above.
@Query("Select c from Car c where c.brand = ?1")
List<Car> findByBrand(String bran);

}

Owner.java Owner.java

package com.packt.cardatabase.domain;

import javax.persistence.*;

import java.util.*;


@Entity
public class Owner 
{
@Id //The primary key is defined by using the @Id annotation
@GeneratedValue(strategy=GenerationType.AUTO) //defines that theID is automatically generated by the database
private long ownerid;
private String firstname, lastname;


//The following  line creates a One to many relationship between Owner and Car
//The cascade attribute means that if the owner is deleted, all linked cars are deleted too.
//The mappedBy="owner" attribute means that the car class has the owner field which is the foreign key for the relationship.
//@OneToMany(cascade = CascadeType.ALL, mappedBy="owner")
//private List<Car> cars;

    public Owner() {}
    //The following was auto generated using source -> Generate Constructor using fields
/**
 * @param ownerid
 * @param firstname
 * @param lastname
 */
    public Owner(String firstname, String lastname) 
    {
    super();
        this.firstname = firstname;
        this.lastname = lastname;
    }

    //The next 3 lines create a many to many relationship and join the columns 'id' and 'owner_id' to a new table called 'car_owner'.
        @ManyToMany(cascade = CascadeType.MERGE)
        @JoinTable(name = "car_owner", joinColumns = {@JoinColumn(name = "ownerid")}, inverseJoinColumns = {@JoinColumn(name = "id")})
    private Set<Car> cars = new HashSet<Car>(0);


    public Set<Car> getCars(){return cars;}
    public void setCars(Set<Car> cars) {this.cars = cars;}  

/*
public List<Car> getCars(){
    return cars;
}

public void setCars(List<Car> cars) {
    this.cars = cars;
}
*/


//The following are auto-generated getters and setters with comments

/**
 * @return the ownerid
 */
public long getOwnerid() {
    return ownerid;
}

/**
 * @param ownerid the ownerid to set
 */
public void setOwnerid(long ownerid) {
    this.ownerid = ownerid;
}

/**
 * @return the firstname
 */
public String getFirstname() {
    return firstname;
}

/**
 * @param firstname the firstname to set
 */
public void setFirstname(String firstname) {
    this.firstname = firstname;
}

/**
 * @return the lastname
 */
public String getLastname() {
    return lastname;
}

/**
 * @param lastname the lastname to set
 */
public void setLastname(String lastname) {
    this.lastname = lastname;
}

}

OwnerRepository.java OwnerRepository.java

package com.packt.cardatabase.domain;

import org.springframework.data.repository.CrudRepository;

public interface OwnerRepository extends CrudRepository<Owner, Long> 
{}

Structure of the files in Eclipse: Eclipse中文件的结构:

在此处输入图片说明

Either remove the Owner field, mark it as @Transient, or make a ManyToOne/OneToMany/OneToOne relationship to it. 删除“所有者”字段,将其标记为@Transient,或与其建立ManyToOne / OneToMany / OneToOne关系。 That's your problem. 那是你的问题。

The problem is with your Car entity has you have defined ManyToOne and ManyToMany for Owner entity, you can fix it by removing below from your Car entity. 问题在于您的Car实体是否已为Owner实体定义了ManyToOneManyToMany ,您可以通过从Car实体中删除以下内容来对其进行修复。

private Owner owner;

Bidirectional mapping should be avoided as it's sometime difficult to manage and create memory problems as both directional entity has to loaded even (can manage by creating query only required data or lazy loading) you don't need sometime so creating a separate embedded ID entity is a great idea. 应避免使用双向映射,因为有时您甚至不需要加载两个定向实体(可以通过仅查询必需的数据或延迟加载来进行管理),因此有时很难管理和创建内存问题,因此创建一个单独的嵌入式ID实体非常必要。好主意。

This is how you can manage it. 这就是您可以对其进行管理的方式。

 @Entity
 public class CarOwner implements Serializable {

    @EmbeddedId
    private CarOwneId id;

    @ManyToOne
    @JoinColumn(name = "car_id", referencedColumnName = "car_id", insertable = false, updatable = false)
    private Car car;

    @ManyToOne
    @JoinColumn(name = "owner_id", referencedColumnName = "owner_id", insertable = false, updatable = false)
    private Owner owner;


    public CarOwner(Car c, Owner o) {
        // create primary key
        this.id = new CarOwneId(c.getId(), o.getOwnerid());

        // initialize attributes
        this.car = c;
        this.owner = o;
    }

    public CarOwneId getId() {
        return id;
    }

    public void setId(CarOwneId id) {
        this.id = id;
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    public Owner getOwner() {
        return owner;
    }

    public void setOwner(Owner owner) {
        this.owner = owner;
    }

    @Embeddable
    public static class CarOwneId implements Serializable {

        @Column(name = "car_id")
        protected Long carId;

        @Column(name = "owner_id")
        protected Long ownerId;

        public CarOwneId() {

        }

        public CarOwneId(Long carId, Long ownerId) {
            this.carId = carId;
            this.ownerId = ownerId;
        }

        public Long getCarId() {
            return carId;
        }

        public void setCarId(Long carId) {
            this.carId = carId;
        }

        public Long getOwnerId() {
            return ownerId;
        }

        public void setOwnerId(Long ownerId) {
            this.ownerId = ownerId;
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 org.hibernate.MappingException:无法确定以下类型:表:对于列:[org.hibernate.mapping.Column(plant) - org.hibernate.MappingException: Could not determine type for: at table: for columns: [org.hibernate.mapping.Column(plant) 无法确定以下表的类型:org.json.JSONObject,在表:ordersinfo中,用于列:[org.hibernate.mapping.Column(items)] - Could not determine type for: org.json.JSONObject, at table: ordersinfo, for columns: [org.hibernate.mapping.Column(items)] 无法确定以下类型的字符串:字符串,在表:STUDENT,对于列:[org.hibernate.mapping.Column(SNAME)] - Could not determine type for: String, at table: STUDENT, for columns: [org.hibernate.mapping.Column(SNAME)] 无法确定类型 <DataType> 在表:TableX中,用于org.hibernate.mapping.Column(userPrefs)列 - could not determine type for <DataType> at table: TableX, for columns org.hibernate.mapping.Column(userPrefs) org.hibernate.MappingException:无法确定类型:java.util.Set,在表:Company中,用于列:[org.hibernate.mapping.Column(users)] - org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: Company, for columns: [org.hibernate.mapping.Column(users)] org.hibernate.MappingException:无法确定类型:java.util.List,在表:大学,列:[org.hibernate.mapping.Column(students)] - org.hibernate.MappingException: Could not determine type for: java.util.List, at table: College, for columns: [org.hibernate.mapping.Column(students)] org.hibernate.MappingException:无法确定类型:java.util.List,在表:user处,用于列:[org.hibernate.mapping.Column(events)] - org.hibernate.MappingException: Could not determine type for: java.util.List, at table: user, for columns: [org.hibernate.mapping.Column(events)] 引起:org.hibernate.MappingException:无法确定类型:时间戳,列:[org.hibernate.mapping.Column(***)] - Caused by: org.hibernate.MappingException: Could not determine type for: Timestamp, for columns: [org.hibernate.mapping.Column(***)] 无法确定类型:java.util.List,在表:file_post,列:[org.hibernate.mapping.Column(file)] - Could not determine type for: java.util.List, at table: file_post, for columns: [org.hibernate.mapping.Column(file)] 无法确定类型:TIMESTAMP,表:BATCH_JOB_CONFIG_DTLS,列:[org.hibernate.mapping.Column(ADD_USER_DTM)] - Could not determine type for: TIMESTAMP, at table: BATCH_JOB_CONFIG_DTLS, for columns: [org.hibernate.mapping.Column(ADD_USER_DTM)]
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM