未使用迁移查询的默认值创建jpa实体

uxhixvfz  于 2021-07-08  发布在  Java
关注(0)|答案(2)|浏览(277)

我正在添加一个新列, signature ,到我现有的 user 表—使用flyawaydb进行数据库迁移—其中新列将具有新用户和现有用户的默认值。但是,我注意到,当我尝试创建和保存新用户时,由于某些原因,该字段为空。
我不知道这是否是某个缓存问题(例如,它在我的 V2__adding_signature.sql 如果执行了迁移查询)或其他操作。
以下是我所拥有的:
实体

@Entity
@Table(name = "users")
@Data
@Builder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
@DynamicUpdate
public class UserEntity {
  @Id private String userId;

  @Column(insertable = false, updatable = false)
  private String signature;

  public UserEntity(String userId) {
    this.userId = userId;
  }
}

服务

@Service
@AllArgsConstructor
public class UserService {

  private final UserRepository userRepo;

  @Transactional
  public UserEntity createUser(String userId) {
    UserEntity userEntity = new UserEntity(userId);
    userRepo.saveAndFlush(userMappingEntity);
    return userEntity; // this will not have a the default signature created
  }
}

存储库

@Repository
public interface UserRepository extends JpaRepository<UserEntity, String> {

....
}

在my db.migration文件夹中设置初始postgres db(对于flywaydb)
v1\uu initial\u creation.sql版本

CREATE TABLE IF NOT EXISTS users (
  user_id TEXT PRIMARY KEY
);

v2\添加\签名.sql

ALTER TABLE users
    ADD COLUMN signature TEXT NOT NULL DEFAULT 'testValueForNow';

编辑\u 1:
我还尝试使用entitymanager刷新我的实体,就像这样

@PersistenceContext private EntityManager entityManager;

      @Transactional
      public UserEntity createUser(String userId) {
        UserEntity userEntity = new UserEntity(userId);
        userRepo.saveAndFlush(userEntity);
        entityManager.refresh(userEntity);

        return userEntity; // this will not have a the default signature created
      }

但是,这似乎也不起作用,并给我以下错误: java.lang.IllegalArgumentException: Entity not managed 编辑2:感谢用户@simon martinelli
我必须做以下工作才能让它工作:

UserEntity userEntity = new UserEntity(userId);
   userEntity = userRepo.saveAndFlush(userEntity);
   entityManager.refresh(entityManager.merge(userEntity));
   return userEntity;
xoshrz7s

xoshrz7s1#

你应该使用 @Generated 的注解 signature 以这种方式输入字段:

@Generated(value = GenerationTime.ALWAYS)
@Column(insertable = false, updatable = false)
private String signature;

因此,hibernate将能够在实体被持久化或更新之后获取属性。
另一个问题是以下代码:

@Transactional
public UserEntity createUser(String userId) {
   UserEntity userEntity = new UserEntity(userId);
   userRepo.saveAndFlush(userMappingEntity);
   return userEntity; // this will not have a the default signature created
}

如果您确信 userId 不存在。但是当用户 userId 实际上存在于数据库的列中 signature 无法获取。所以,你应该这样纠正这个方法:

@Transactional
public UserEntity createUser(String userId)
{
   Optional<User> user = userRepo.findById(userId);
   if (user.isPresent()) return user.get();

   UserEntity userEntity = new UserEntity(userId);
   return userRepo.save(userEntity);
}

我猜是的 saveAndFlush 可以替换为 save 因为不管怎样冲洗都会在最后完成 createUser 方法标记为 @Transactional .

goqiplq2

goqiplq22#

默认值仅适用于数据库。
插入后,必须刷新实体才能从数据库中获取插入的默认值。

相关问题