【问题标题】:Transition from Entity to DTO从实体到 DTO 的转换
【发布时间】:2018-03-09 11:53:09
【问题描述】:

我想在所有类中使用 DTO 对象,但是当我从任何地方将 User> 更改为 UserDTO> 时出现错误。

我的错误日志是;

org.springframework.beans.factory.UnsatisfiedDependencyException: 创建名为“userService”的 bean 时出错:不满足的依赖关系 通过字段“userRepository”表示;嵌套异常是 org.springframework.beans.factory.BeanCreationException:错误 创建名为“userRepository”的 bean:调用 init 方法 失败的;嵌套异常是 java.lang.IllegalArgumentException: Not a 托管类型:类 de.javatar81.examples.domain.UserDTO

引起:org.springframework.beans.factory.BeanCreationException: 创建名为“userRepository”的 bean 时出错:调用 init 方法失败;嵌套异常是 java.lang.IllegalArgumentException: 不是托管类型:类 de.javatar81.examples.domain.UserDTO

原因:java.lang.IllegalArgumentException:不是托管类型: 类 de.javatar81.examples.domain.UserDTO

User.class;

    @Entity
    @Table(name="USER")
    public class User implements Serializable {

        private static final long serialVersionUID = -7860243025833384447L;

        @Id
        private Long id;

        private String login;
        private String firstName;
        private String lastName;
        private Date dayOfBirth;
        @ManyToOne
        private User manager;

//setters and getters

    }

UserDTO.class;

    public class UserDTO implements Serializable {

        private static final long serialVersionUID = -7860243025833384447L;

        private Long id;
        private String login;
        private String firstName;
        private String lastName;
        private Date dayOfBirth;
        private String city;
        private String district;

//setters and getters

    }

UserRepository.class;

public interface UserRepository extends PagingAndSortingRepository<UserDTO, Long>, JpaSpecificationExecutor<UserDTO>, JpaRepository<UserDTO, Long>, Repository<UserDTO, Long>{
    @Query(value = "select * from user where login like :filters% order by login \n-- #pageable\n",
    countQuery = "select count(*) from user where login like :filters%",
    nativeQuery = true)
    Page<UserDTO> findByLogin(@Param("filters") String filters, Pageable pageable);
}

UserService.class;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public Page<UserDTO> findByFilter(Map<String, String> filters, Pageable pageable) {
        return userRepository.findAll(getFilterSpecification(filters), pageable);
    }

    public Page<UserDTO> findByLogin(String filters, Pageable pageable) {
        return userRepository.findByLogin(filters.toLowerCase(), pageable);
    }

    @Transactional
    public void create(UserDTO user) {
        userRepository.save(user);
    }

    private Specification<UserDTO> getFilterSpecification(Map<String, String> filterValues) {
        return (Root<UserDTO> root, CriteriaQuery<?> query, CriteriaBuilder builder) -> {
            Optional<Predicate> predicate = filterValues.entrySet().stream()
                    .filter(v -> v.getValue() != null && v.getValue().length() > 0)
                    .map(entry -> {
                        Path<?> path = root;
                        String key = entry.getKey();
                        if (entry.getKey().contains(".")) {
                            String[] splitKey = entry.getKey().split("\\.");
                            path = root.join(splitKey[0]);
                            key = splitKey[1];
                        }
                        return builder.like(path.get(key).as(String.class), "%" + entry.getValue() + "%");
                    })
                    .collect(Collectors.reducing((a, b) -> builder.and(a, b)));
            return predicate.orElseGet(() -> alwaysTrue(builder));
        };
    }

    private Predicate alwaysTrue(CriteriaBuilder builder) {
        return builder.isTrue(builder.literal(true));
    }

}

UserBean.class;

@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST)
public class UserBean {

    @Autowired
    private UserService userService;
    private UserLazyDataModel users;

    @PostConstruct
    private void init() {
        this.users = new UserLazyDataModel(userService);
    }

    public UserLazyDataModel getUsers() {
        return users;
    }
}

UserLazyDataModel.class;

public class UserLazyDataModel extends LazyDataModel<UserDTO> implements SelectableDataModel<UserDTO> {

    private static final long serialVersionUID = -6123945723069023025L;
    private final transient UserService userService;
    private static final SortOrder DEFAULT_SORT_ORDER = SortOrder.ASCENDING;
    private static final String DEFAULT_SORT_FIELD = "id";
    private String columnName;
    private String filter;

    public UserLazyDataModel(UserService userService) {
        this.userService = userService;
    }

    @Override
    public Object getRowKey(UserDTO user) {
        return user.getId();
    }

    @Override
    public UserDTO getRowData(String rowKey) {
        Long rowId = Long.valueOf(rowKey);
        @SuppressWarnings("unchecked")
        List<UserDTO> users = (List<UserDTO>) super.getWrappedData();
        return users.stream().filter(user -> user.getId().equals(rowId)).findAny().orElse(null);
    }

    @Override
    public List<UserDTO> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String, Object> filters) {
        Sort sort = new Sort(getDirection(DEFAULT_SORT_ORDER), DEFAULT_SORT_FIELD);
        if (multiSortMeta != null) {
            List<Order> orders = multiSortMeta.stream()
                    .map(m -> new Order(getDirection(m.getSortOrder() != null ? m.getSortOrder() : DEFAULT_SORT_ORDER),
                            m.getSortField()))
                    .collect(Collectors.toList());
            sort = new Sort(orders);
        }
        return filterAndSort(first, pageSize, filters, sort);
    }

    @Override
    public List<UserDTO> load(int first, int pageSize, String sortField, SortOrder sortOrder,
            Map<String, Object> filters) {
        Sort sort = null;
        if (sortField != null) {
            sort = new Sort(getDirection(sortOrder != null ? sortOrder : DEFAULT_SORT_ORDER), sortField);
        } else if (DEFAULT_SORT_FIELD != null) {
            sort = new Sort(getDirection(sortOrder != null ? sortOrder : DEFAULT_SORT_ORDER), DEFAULT_SORT_FIELD);
        }
        return filterAndSort(first, pageSize, filters, sort);
    }

    private List<UserDTO> filterAndSort(int first, int pageSize, Map<String, Object> filters, Sort sort) {
        Map<String, String> filtersMap = filters.entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().toString()));

        if (!filters.isEmpty()) {
            filters.forEach((k, v) -> {
                columnName = new String(k.toString());
                filter = new String(v.toString());
            });
        } else {
            columnName = new String("login");
            filter = new String("");
        }

        Page<UserDTO> page = userService.findByFilter(filtersMap, new PageRequest(first / pageSize, pageSize, sort));
        Page<UserDTO> pageLogin = userService.findByLogin(filter, new PageRequest(first / pageSize, pageSize));
        this.setRowCount(((Number) pageLogin.getTotalElements()).intValue());
        this.setWrappedData(pageLogin.getContent());
        return pageLogin.getContent();
    }

    private static Direction getDirection(SortOrder order) {
        switch (order) {
        case ASCENDING:
            return Direction.ASC;
        case DESCENDING:
            return Direction.DESC;
        case UNSORTED:
        default:
            return null;
        }
    }
}

index.xhtml;

<?xml version="1.0"?>
<ui:composition xmlns:f="http://java.sun.com/jsf/core"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:pe="http://primefaces.org/ui/extensions">
    <h:head>
    </h:head>
    <h:body styleClass="login">
        <f:view transient="true">
            <h:form id="form">
                <p:dataTable var="users" value="#{userBean.users}" paginator="true"
                    rows="10" sortMode="multiple"
                    paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
                    rowsPerPageTemplate="5,10,15" selectionMode="single" id="userTable"
                    lazy="true">
                    <p:column headerText="Id" sortBy="#{users.id}" filterBy="#{users.id}">
                        <h:outputText value="#{users.id}" />
                    </p:column>
                    <p:column headerText="Login" sortBy="#{users.login}"
                        filterBy="#{users.login}">
                        <h:outputText value="#{users.login}" />
                    </p:column>
                    <p:column headerText="Firstname" sortBy="#{users.first_Name}"
                        filterBy="#{users.firstName}">
                        <h:outputText value="#{users.firstName}" />
                    </p:column>
                    <p:column headerText="Lastname" sortBy="#{users.lastName}"
                        filterBy="#{users.lastName}">
                        <h:outputText value="#{users.lastName}" />
                    </p:column>
                    <p:column headerText="DayOfBirth" sortBy="#{users.dayOfBirth}"
                        filterBy="#{users.dayOfBirth}">
                        <h:outputText value="#{users.dayOfBirth}" />
                    </p:column>
                    <p:column headerText="Manager" sortBy="#{users.manager.lastName}"
                        filterBy="#{users.manager.lastName}">
                        <h:outputText value="#{users.manager.lastName}" />
                    </p:column>
                </p:dataTable>
            </h:form>
        </f:view>
    </h:body>
</ui:composition>

我还需要做什么?

【问题讨论】:

  • 据我了解,您的存储库类使用 User 作为其实体而不是 UserDTO
  • 如何将其转换为 DTO? @amRika
  • 首先,检查它是否解决了您的beanNotFound异常问题
  • 是的 .. 请在存储库类中使用 User 而不是 UserTO 尝试一次,让我知道它是否适合您。
  • 它有效,谢谢!但它在我的 H2 控制台上创建了另一个名为 UserDTO 的表,这使得理解为我使用 DTO 的主要原因变得更加复杂。就我而言,DTO 应该使用与主实体对象相同的类。我错了吗? @amRika

标签: java spring dto


【解决方案1】:
public interface UserRepository extends PagingAndSortingRepository<UserDTO, Long>, JpaSpecificationExecutor<UserDTO>, JpaRepository<UserDTO, Long>, Repository<UserDTO, Long>{
@Query(value = "select * from user where login like :filters% order by login \n-- #pageable\n",
countQuery = "select count(*) from user where login like :filters%",
nativeQuery = true)
Page<UserDTO> findByLogin(@Param("filters") String filters, Pageable pageable);}

通过查看 UserRepository,似乎没有创建 UserRepository 的 bean,因为您忘记使用 @Repository 注释对存储库进行注释。

您必须使用@Repository(为组件/类创建 Bean 的 Spring 原型)注释 UserRepository。因此,在创建 UserRepository 的 bean 之后,您将能够执行您的操作。

【讨论】:

  • 但是在我创建 DTO 类之前,存储库类可以直接与实体类一起正常工作。
【解决方案2】:

我在这段代码中没有看到任何注释。你应该写它们:)

public class UserDTO implements Serializable {

    private static final long serialVersionUID = -7860243025833384447L;

    private Long id;
    private String login;
    private String firstName;
    private String lastName;
    private Date dayOfBirth;
    private String city;
    private String district;

 //setters and getters

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-16
    • 2014-07-20
    • 2019-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-10
    相关资源
    最近更新 更多