Java应用开发各种奇葩BUG
1、Lombok
1.1 创建子类,无法对父类属性进行赋值
- @Data 和@Builder 不可以混用
@Builder 和 @Data 搭配使用,导致生成的构造器是可变的,它允许使用 setter 方法修改构造器的状态。这违反了构造器模式的原则,构造器应该是不可变的,一旦创建就不能被修改。
**注意:**如果非要使用 @Builder ,那么不要用 @Data ,要用 @Getter。相对来说,反而 @Accessors 的行为更符合这个要求。 - @Data 无法对父类属性进行赋值
- @Data注解可以用来生成类的getter、setter、构造方法和toString方法。然而,默认情况下,它只会考虑当前类中存在的属性(字段),而不会考虑其父类中的属性。如果你希望@Data也考虑父类中的属性,需要使用@Accessors注解和@Data一起使用。
@Accessors(fluent=true)
public class Parent {
private int parentProperty;
}
@Data
public class Child extends Parent {
private int childProperty;
}
Child child = new Child();
child.setParentProperty(10);
child.setChildProperty(20);
System.out.println(child); // prints Child{parentProperty=10, childProperty=20}
- 如果父类用了@Data 此时子类如何给父类属性赋值
如果父类使用了@Data注解,子类可以通过以下两种方式给父类复制属性: 使用@Accessors(fluent=true)注解:在子类上添加@Accessors(fluent=true)注解,可以使得子类的属性可以通过链式调用的方式进行赋值,这样就可以使用子类给父类复制属性。例如:
@Data
public class Parent {
private String name;
}
@Data
@Accessors(fluent=true)
public class Child extends Parent {
private String age;
}
Child child = new Child();
child.setName("John").setAge("18");
Parent parent = child.toParent();
- 使用@AccessorsPrefix注解:在子类上添加@AccessorsPrefix注解,可以为子类的属性指定前缀,以区分子类和父类的属性。例如:
@Data
public class Parent {
private String name;
}
@Data
@Accessors(prefix = "p")
public class Child extends Parent {
private String age;
}
Child child = new Child();
child.setName("John").setAge("18");
Parent parent = child.toParent();
- @AllArgsConstructor 构造函数 无法初始化父类的属性
@AllArgsConstructor注解只能用来生成具有指定参数的构造函数,它并不会初始化父类的属性。 如果希望初始化父类的属性,可以在子类的@AllArgsConstructor注解的父类属性上添加@ToString(callSuper = true);
@EqualsAndHashCode(callSuper = true) - @ToString(callSuper =true) 实现toString 属性覆盖父类
- @EqualsAndHashCode(callSuper = true)覆盖父类
2、MybatisPLus
2.1 MybatisPLus自动填充公共参数
在MyBatis Plus中,可以使用@FillInsert和@FillUpdate注解来自动填充公共参数。 @FillInsert:用于填充insert操作的公共参数,默认情况下,会将注解所在的字段自动添加到插入语句中。 @FillUpdate:用于填充update操作的公共参数,默认情况下,会将注解所在的字段自动添加到更新语句中。 示例代码如下:
public class BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 搜索值
*/
@JsonIgnore
@TableField(exist = false)
private String searchValue;
/**
* 创建者
*/
@TableField(fill = FieldFill.INSERT)
private String createBy;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 更新者
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateBy;
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
/**
* 请求参数
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@TableField(exist = false)
private Map<String, Object> params = new HashMap<>();
}
- 添加配置
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import java.util.Date;
/**
* MP注入处理器
*
* @Author: water
* @Date: 2023/11/15 8:51
* @Version: 1.0.0
*/
@Slf4j
public class CreateAndUpdateMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
try {
if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseEntity) {
BaseEntity baseEntity = (BaseEntity) metaObject.getOriginalObject();
Date createTime = ObjectUtil.isNotNull(baseEntity.getCreateTime())
? baseEntity.getCreateTime() : new Date();
Date updateTime = ObjectUtil.isNotNull(baseEntity.getUpdateTime())
? baseEntity.getUpdateTime() : new Date();
// 解析了有数据填充的问题
baseEntity.setCreateTime(createTime);
baseEntity.setUpdateTime(updateTime);
String username = StringUtils.isNotBlank(baseEntity.getCreateBy())
? baseEntity.getCreateBy() : getLoginUsername();
// 当前已登录 且 创建人为空 则填充
baseEntity.setCreateBy(username);
// 当前已登录 且 更新人为空 则填充
baseEntity.setUpdateBy(username);
}
} catch (Exception e) {
throw new ServiceException("自动注入异常 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);
}
}
@Override
public void updateFill(MetaObject metaObject) {
try {
if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseEntity) {
BaseEntity baseEntity = (BaseEntity) metaObject.getOriginalObject();
Date current = new Date();
// 更新时间填充(不管为不为空)
baseEntity.setUpdateTime(current);
String username = getLoginUsername();
// 当前已登录 更新人填充(不管为不为空)
if (StringUtils.isNotBlank(username)) {
baseEntity.setUpdateBy(username);
}
}
} catch (Exception e) {
throw new ServiceException("自动注入异常 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);
}
}
/**
* 获取登录用户名
*/
private String getLoginUsername() {
LoginUser loginUser;
try {
loginUser = LoginHelper.getLoginUser();
} catch (Exception e) {
log.warn("自动注入警告 => 用户未登录");
return null;
}
return ObjectUtil.isNotNull(loginUser) ? loginUser.getUsername() : null;
}
}
3、开发问题
3.1 detected dubious ownership in repository XXX
原因:Git 安全漏洞 CVE-2022-24765 所有权问题
解决方案一:一行代码搞定
git config --global --add safe.directory "*";
解决方案二:
# 示例代码:添加Git安全目录例外
git config --global --add safe.directory D:\a\c