简体   繁体   中英

Hibernate problems with join fetch “Cannot join to attribute of basic type”

I'm having problems with loading entities with a one-to-one relationship from a sqlite database. When I use a plain CriteriaQuery to load them everything works fine. But I've read somwhere that for the performance it's better to join the two tables the data is coming from in the query so hibernate won't make 2 queries out of it.

I am getting a BasicPathUsageException: Cannot join to attribute of basic type when I am trying to create a Fetch thingy.

This is the method I use to create the query:

    private List<Task> loadTasks() {
        
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            session.beginTransaction();
            
            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaQuery<Task> taskQuery = builder.createQuery(Task.class);
            Root<Task> taskTable = taskQuery.from(Task.class);

            Fetch<Task, TaskType> fetch = taskTable.fetch(TaskType_.ID, JoinType.LEFT);    //<- exception is pointing here
            taskQuery.where(builder.equal(taskTable.get(TaskType_.ID).get("status"), "RECEIVED"));
            
            List<Task> loadedTasks= session.createQuery(taskQuery).getResultList();
            session.getTransaction().commit();
            
            return loadedTasks;
            
        } catch (Exception e) {
            
            e.printStackTrace();
            return null;
        }
    }

This is the TaskType class:

@Entity(name = "TaskType")
@Table(name = "task_types")
public class TaskType implements Serializable {
    
    private final SimpleIntegerProperty id = new SimpleIntegerProperty();
    private final SimpleStringProperty name = new SimpleStringProperty();
    
    @Id
    @Column(name = "task_type_id", unique = true)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public int getId() {
        return id.get();
    }
    
    public void setId(int id) {
        this.id.set(id);
    }
    
    @Column(name = "task_type_name", unique = true)
    public String getName() {
        return name.get();
    }
    
    public void setName(String name) {
        this.name.set(name);
    }
    
    public SimpleIntegerProperty idProperty() {
        return id;
    }
    
    public SimpleStringProperty nameProperty() {
        return name;
    }

And this is the Task class which contains a task type object:

@Entity(name = "Task")
@Table(name = "tasks")
public class Task implements Serializable {
    
    private final SimpleIntegerProperty id = new SimpleIntegerProperty();
    private final SimpleStringProperty name = new SimpleStringProperty();
    private TaskType type;
    
    @Id
    @Column(name = "task_id", unique = true)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public int getId() {
        return id.get();
    }
    
    public void setId(int id) {
        this.id.set(id);
    }
    
    @Column(name = "task_name", unique = true)
    public String getName() {
        return name.get();
    }
    
    public void setName(String name) {
        this.name.set(name);
    }
    
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "task_type_id")
    public TaskType getType() {
        return type;
    }
    
    public void setType(TaskType type) {
        this.type = type;
    }
    
    public SimpleStringProperty nameProperty() {
        return name;
    }
    
    public SimpleIntegerProperty idProperty() {
        return id;
    }

How is this fetch() supposed to be used or how can I get the code to load all tasks including their task types? Am I using some annotation wrong?

I tried to look the exception up but I could not find any solution or understand how to apply it to my situation.

Thanks for any help!

The fetch method, just like the join methods, only work on associations.

You use the following instead

taskTable.fetch(Task_.TYPE, JoinType.LEFT);
taskQuery.where(builder.equal(taskTable.get(Task_.TYPE).get("status"), "RECEIVED"));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM