【Java】异常总结

一、java.util.ConcurrentModificationException

对Vector、ArrayList在迭代的时候如果同时对其进行修改就会抛出java.util.ConcurrentModificationException异常。

比如遍历时对自己进行remove()就会出现java.util.ConcurrentModificationException异常:

List<String> strings;
for(String s : strings){
	if("".equals(s)){
		strings.remove(s);
	}
}

解决办法:

List<String> strings;
List<String> rStrings = new ArrayList<>(rStrings);
for(String s :rStrings){
	if("".equals(s)){
		strings.remove(s);
	}
}

或者(推荐使用迭代器安装删除!)


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Review_1 {
    public static void main(String[] args){
 
        List<String> list = new ArrayList<String>();
        list.add("20161127");
        list.add("20161127asdf");
        list.add("20161127asdf");
        list.add("20161127asdf");
        list.add("20161127asdf");
        list.add("20161127asdf");
        list.add("20161127asdf");
 
        //1.i--操作
        for(int i = 0;i < list.size();i++) {
            String b = list.get(i);
            if (b.equals("20161127asdf")) {
                list.remove(i);
                i--;
            }
        }
        System.out.println(list.size());
 
        list.add("20161127asdf");
        list.add("20161127asdf");
        list.add("20161127asdf");
        list.add("20161127asdf");
        list.add("20161127asdf");
        list.add("20161127asdf");
        //2.反向遍历
        for(int i = list.size() - 1;i >= 0;i--){
            String b = list.get(i);
            if(b.equals("20161127asdf")){
                list.remove(i);
            }
        }
        System.out.println(list.size());
 
        list.add("20161127asdf");
        list.add("20161127asdf");
        list.add("20161127asdf");
        list.add("20161127asdf");
        list.add("20161127asdf");
        list.add("20161127asdf");
        //3.调用Iterator的remove()方法安全删除元素,避免异常
        Iterator<String> iter = list.iterator();
        while(iter.hasNext()){
            String b = iter.next();
            if(b.equals("20161127asdf")){
                iter.remove();
            }
        }
        System.out.println(list.size());
 
    }
}

关于线程影响:Java ConcurrentModificationException异常原因和解决方法

二、java.lang.UnsupportedOperationException

1.如果map或者list是强制转换过得在remove()和add()时可能会抛出此异常,如bean(Object)被转成beanMap时,beanMap不具备hashmap等常见的remove()方法,需要自己实现或者将bean转成hashmap即可避免

其他见解:java异常java.lang.UnsupportedOperationException解决方法
2.如何是将Array转成ArrayList的话方法有误也会产生这个问题,比如:

String[] arr = "test";
List<String> list = Arrays.asList<arr>;

Arrays.asList()会返回一个ArrayList,但是要特别注意,这个ArrayList是Arrays类的静态内部类,并不是java.util.ArrayList类。java.util.Arrays.ArrayList类实现了set(), get(),contains()方法,但是并没有实现增加元素的方法(事实上是可以调用add方法,但是没有具体实现,仅仅抛出UnsupportedOperationException异常),因此它的大小也是固定不变的。
正确的操作是:

String[] arr = "test";
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));

ArrayList的构造方法可以接收一个Collection类型,而java.util.Arrays.ArrayList已经实现了该接口。

三、The server time zone value ‘Öйú±ê׼ʱ¼ä’ is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support. -> [Help 1]

这是抛出的JDBC时区异常,出现于saas项目。通用一点的方法就是修改connectionURL调整时区或者修改MySQL配置信息,解决方案链接。但其他项目都没有类似问题,数据库连接正常,按照解决方案修改了也不行,查证后原来不是web包报错而是domin包中mybatis-generator报错啊,定位到domin包中generatorConfig.xml,发现url如下:
connectionURL="jdbc:mysql://127.0.0.1:3306/saas?characterEncoding=utf8",按照解决方案添加时区后如下:
connectionURL="jdbc:mysql://127.0.0.1:3306/saas?characterEncoding=utf8?serverTimezone=GMT%2B8"仍然报错,不过时字符问题,在“”中使用xml中使用&、<、>、+等需要转义,所以修改为如下URL:connectionURL="jdbc:mysql://127.0.0.1:3306/saas?characterEncoding=utf8&amp;serverTimezone=GMT%2B8"问题解决。
附:xml转义字符表(不可省略)

实体引用含义
&(逻辑与)&amp;
<(小于)&lt;
>(大于)&gt;
"(双引号)&quot;
'(单引号)&apos;

四、方法抛出 ‘java.lang.ArrayStoreException’ 异常

这是由于转换的时候类型不一致导致的异常。
问题复现:

List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
String a = String.join(",",ids.toArray(new String[ids.size()]));//将list中的元素按“,”分割成字符串

由于ids的类型是Integer,通过String.join()转换时类型不一致抛出异常。
正解:将Integer替换成String

List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
List< String> list = ids.stream().map(t->String.format("%s",t)).collect(toList());  //方法有多种
String b = String.join(",",list.toArray(new String[list.size()]));//将list中的元素按“,”分割成字符串

五、org.hibernate.MappingException: Unknown entity异常

具体异常如下:

org.hibernate.MappingException: Unknown entity异常详细信息如下:
org.hibernate.MappingException: Unknown entity: com.hucong.model.TestEntity
at org.hibernate.impl.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:628)
at org.hibernate.impl.SessionImpl.getEntityPersister(SessionImpl.java:1366)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
······

问题复现:

  • 实体类TestEntity:
@Data
@Table(name = "bi_inventory")
@DynamicInsert
@DynamicUpdate
@JsonIgnoreProperties(ignoreUnknown = true)
public class InventoryDetail extends IdEntity {
    private Integer officeId;   //站点id
    @JsonFormat(pattern="yyyy-MM-dd",timezone="GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date inventoryDate;   //盘点日期
    private String pics;   //图片id,多个图片用逗号拼接

	@Transient
    private List<InventoryDetail> details;//详情
    @Transient
    private String officeName;//站点名称
    @Transient
    private String createdByName;//创建人

    //helper
    @JsonFormat(pattern="yyyy-MM-dd",timezone="GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @Transient
    private Date beginDate;  //搜索开始时间
    @JsonFormat(pattern="yyyy-MM-dd",timezone="GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @Transient
    private Date endDate;  //搜索截止时间
    @Transient
    private String officeIds;
}
  • hibernate的实现类TestEntityDaoImpl.java:
@Repository
public class InventoryDaoImpl extends BaseDaoImpl<Inventory> implements InventoryDao {
    public InventoryDaoImpl(){super(Inventory.class);}

    @Override
    public List<Inventory> selectByPage(MyPage<Inventory> page){
        String sql = "select " +
                "bi.id, " +
                "bi.office_id as officeId, " +
                "bi.pics, " +
                "DATE_FORMAT(bi.inventory_date,'%Y-%m-%d %H:%i:%S') AS inventoryDate," +
                "DATE_FORMAT(bi.created_date,'%Y-%m-%d %H:%i:%S') AS createdDate," +
                "so.name as officeName " +
                "from bi_inventory bi "+
                "left join sys_office so on so.id = bi.office_id "+
                "where 1=1 "+
                "and bi.del_flag = "+Inventory.DEL_FLAG_NORMAL+" "+
                "and bi.office_id in ("+page.getOfficeIds()+") ";
                if(page.getEntity().getBeginDate()!=null){
                    sql += " and bi.inventory_date >= "+ DateUtils.getBeginDate(page.getEntity().getBeginDate());
                }
                if (page.getEntity().getEndDate()!=null){
                    sql +=" and bi.inventory_date <= "+ DateUtils.getEndDate(page.getEntity().getEndDate());
                }

        return findListBySql(sql,inventory.class);
    }
}

从网上找了很久基本都是说注解的包没导对或者配置有问题,最后发现其实是最基本的注解@Entity都没有加。。。所在在实体类上加上注解@Entity即可

后续: 直接增加@Entity注解还是有问题的,会在项目运行时报错:

xxx.Invocation of init method failed; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.List, at table: bi_inventory, for columns: [org.hibernate.mapping.Column(details)]

意思是private List<TestEntityDetail> details;这个成员变量有问题,实测过程中无论在前面加不加@Transient都会报这个错误,所以对于头表,也就有是private List<Entity> details属性的实体类暂时只能单独处理,即不加@Data这个注解,手动实现setter、getter方法,@Transient这个注解要么加在getter方法上,要么加在成员变量上,不能都加。
修改后的实体类如下:

Entity
@Data
@Table(name = "bi_inventory")
@DynamicInsert
@DynamicUpdate
@JsonIgnoreProperties(ignoreUnknown = true)
public class Inventory extends IdEntity {
    private Integer officeId;   //站点id
    @JsonFormat(pattern="yyyy-MM-dd",timezone="GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date inventoryDate;   //盘点日期
    private String pics;   //图片id,多个图片用逗号拼接

    private List<InventoryDetail> details;//详情
    private String officeName;//站点名称
    private String createdByName;//创建人

    //helper
    @JsonFormat(pattern="yyyy-MM-dd",timezone="GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date beginDate;  //搜索开始时间
    @JsonFormat(pattern="yyyy-MM-dd",timezone="GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date endDate;  //搜索截止时间
    private String officeIds;

    public Integer getOfficeId() {
        return officeId;
    }

    public void setOfficeId(Integer officeId) {
        this.officeId = officeId;
    }

    public Date getInventoryDate() {
        return inventoryDate;
    }

    public void setInventoryDate(Date inventoryDate) {
        this.inventoryDate = inventoryDate;
    }

    @Transient
    public String getOfficeName() {
        return officeName;
    }

    public void setOfficeName(String officeName) {
        this.officeName = officeName;
    }

    @Transient
    public String getCreatedByName() {
        return createdByName;
    }

    public void setCreatedByName(String createdByName) {
        this.createdByName = createdByName;
    }

    @Transient
    public Date getBeginDate() {
        return beginDate;
    }

    public void setBeginDate(Date beginDate) {
        this.beginDate = beginDate;
    }

    @Transient
    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    @Transient
    public String getOfficeIds() {
        return officeIds;
    }

    public void setOfficeIds(String officeIds) {
        this.officeIds = officeIds;
    }

    @Transient
    public List<InventoryDetail> getDetails() {
        return details;
    }

    public void setDetails(List<InventoryDetail> details) {
        this.details = details;
    }

    public String getPics() {
        return pics;
    }

    public void setPics(String pics) {
        this.pics = pics;
    }
}

参考文档:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值