java---no-parameter construction to achieve reflection

First look at the error message:

java.sql.SQLException: Cannot create com.eshop.entity.SUser: com.eshop.entity.SUser Query: select * from s_user Parameters: []
	at org.apache.commons.dbutils.AbstractQueryRunner.rethrow(AbstractQueryRunner.java:392)
	at org.apache.commons.dbutils.QueryRunner.query(QueryRunner.java:351)
	at org.apache.commons.dbutils.QueryRunner.query(QueryRunner.java:289)
	at com.eshop.util.JdbcUtil.queryList(JdbcUtil.java:49)
	at com.eshop.dao.impl.UserDaoImpl.select(UserDaoImpl.java:12)
	at com.eshop.service.impl.UserServiceImpl.findAll(UserServiceImpl.java:14)
	at com.eshop.controller.UserServlet.findAll(UserServlet.java:17)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.eshop.controller.BaseServlet.service(BaseServlet.java:26)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:544)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:616)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:831)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1634)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

The first step: analysis of the error
Insert picture description here
can be seen here because at com.eshop.util.JdbcUtil.queryList(JdbcUtil.java:49), resulting in Cannot create com.eshop.entity.SUser

Then we first look at whether there is a code error in JdbcUtil, but this is not a code problem, then we return to the entity class that
often uses the default empty constructor, but if you need a parameter constructor, and this parameter is not direct Corresponding to a certain attribute, for example:
Insert picture description here
the parameterized structure here does not directly correspond to a certain attribute. When adding migration, an error will be reported:
Cannot create com.eshop.entity.SUser: com.eshop.entity.SUser Query: select * from s_user Parameters: [] The
solution is very simple, just add a parameterless structure manually.
But in fact, do not want to use this empty constructor, because it will lack some null value detection and other judgments.
Microsoft's eShopOnWeb sample project found the following wording:

public class Order : BaseEntity, IAggregateRoot
{
    
    
    // 注意这里是private
    private Order()
    {
    
    
        // required by EF
    }
 
    // 含参构造函数包括了空值检测
    public Order(string buyerId, Address shipToAddress, List<OrderItem> items)
    {
    
    
        Guard.Against.NullOrEmpty(buyerId, nameof(buyerId));
        Guard.Against.Null(shipToAddress, nameof(shipToAddress));
        Guard.Against.Null(items, nameof(items));
 
        BuyerId = buyerId;
        ShipToAddress = shipToAddress;
        _orderItems = items;
    }
    public string BuyerId {
    
     get; private set; }
 
    public DateTimeOffset OrderDate {
    
     get; private set; } = DateTimeOffset.Now;
    public Address ShipToAddress {
    
     get; private set; }
 
    private readonly List<OrderItem> _orderItems = new List<OrderItem>();
    public IReadOnlyCollection<OrderItem> OrderItems => _orderItems.AsReadOnly();
 
    // ...
}

When EF Core creates an instance, it will first call the parameterless constructor, regardless of the access type of the constructor, so we only need to add a private parameterless constructor!

Guess you like

Origin blog.csdn.net/weixin_44889894/article/details/114256126
Recommended