Как я могу реализовать шаблон Repository, используя Generic Types с Java Spring - PullRequest
0 голосов
/ 11 декабря 2019

Я пытаюсь найти способ реализовать шаблон репозитория с помощью весенней загрузки с типами Generic. До сих пор я изучал эту статью:

https://thoughts -on-java.org / реализовать-шаблон-репозитория-с-jpa-and-hibernate /

и попытался реализовать это решение с использованием универсальных типов на основе решения этого вопроса:

Использование обобщенных методов и методов EntityManager jpa

Я попытался сделать это с помощью JPA иHibernate, но для меня, появляется ошибка, когда я пытаюсь вернуть класс сущности с указанным параметром типа.

Ниже приведена моя модель пользователя с использованием JPA и Hibernate:

package models;

import javax.persistence.*;

@Entity
public class User extends Model {
    @Id
    @Column(name = "id", updatable = false, nullable = false)
    private String id;

    public String username;
    private String password;

    public User(String username, String password) {
        super();
        this.username = username;
        this.password = password;
    }

    public String getPassword() {
        return password;
    }

}

Ниже приведен мой интерфейс для основных операций CRUD:

package repositories;

import models.Model;

import java.util.UUID;

public interface IRepository<T> {
    void add(T entity);
    void delete(String id);
    void update(T entity);
    T get(String id);
    boolean exists(String id);
}

Затем я создал абстрактный класс для всех репозиториев, чтобы избежать повторения для всех Моделей.

package repositories;

import models.Model;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

public abstract class Repository<T> implements IRepository<T>{

    private EntityManager em;

    public Repository(EntityManager em){
        this.em = em;
    }

    @Override
    public void add(T entity) {
        em.persist(entity);
    }

    @Override
    public void delete(String id) {
        T entity = get(id);
        em.remove(entity);
    }

    @Override
    public void update(T entity) {
        em.merge(entity);
    }

    @Override
    public T get(String id) {
        return em.find(getEntityClass(), id);
    }

    public boolean exists(String id) {
        return em.contains(get(id));
    }

    // link to an explanation can be found at:https://stackoverflow.com/questions/40635734/using-generics-and-jpa-entitymanager-methods
    // when a class extends this class, all is needed is to fill out the method body of to return the class.
    public abstract Class<T> getEntityClass();
}

абстрактный класс существует длямне вернуть класс, принадлежащий T

, и это специальный репозиторий для пользователей:

package repositories;
import models.Model;
import models.User;

import javax.persistence.EntityManager;

public class UserRepository<User> extends Repository<User> {

    public UserRepository(EntityManager em) {
        super(em);
    }

    @Override
    public Class<User> getEntityClass() {
        return null;
    }
}

В идеале, для метода getEntityClass я хотел бы вернуть User.class, ноЯ получаю ошибкуили в IDE со словами «Невозможно выбрать переменную типа». Я просмотрел еще несколько вопросов в Интернете, и еще одна вещь, которую пытались люди, это либо поместить параметр типа Class, либо иметь член типа Class в репозитории User. Я попробовал оба метода, и это не сработало, есть идеи?

1 Ответ

1 голос
/ 11 декабря 2019

class UserRepository<User> должно быть просто class UserRepository. В противном случае User аналогично T, универсальному типу. Не класс User.

Но ты изобретаешь колесо. Изучите и используйте Spring Data JPA, который предоставляет универсальные репозитории и многое другое.

...