Вопрос или проблема
Я получаю следующую ошибку и не могу понять, что ее вызывает.
2024-10-19T11:26:28.546+05:30 WARN 9455 --- [rentsysapi] [nio-8080-exec-2] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.data.mapping.PropertyReferenceException: No property 'asset' found for type 'AssetVehicle']
Сущность транспортного средства:
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Entity
@Table(name = "asset_vehicle", schema = "public")
@EntityListeners(AuditingEntityListener.class)
@Audited
public class AssetVehicle extends BaseExpireEntity {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
@UuidGenerator
@Column(updatable = false, nullable = false, columnDefinition = "UUID")
private UUID assetVehicleId;
@Enumerated(value = EnumType.STRING)
@Column(nullable = false)
private AssetStatus status = AssetStatus.AVAILABLE;
private String vehicleNumber;
private String vin;
private String enginNumber;
private String chassisNumber;
private String color;
/// Год выпуска
private Integer yom;
/// Год регистрации
private Integer yor;
@Column(columnDefinition = "TEXT")
private String remark;
@Column(nullable = false, updatable = false)
private UUID primaryBranchId;
//region отношения
@ManyToOne
@JoinColumn(name = "company_id", nullable = false, updatable = false)
private Company company;
@ManyToOne
@JoinColumn(name = "owner_id")
private UserEntity owner;
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "vehicle_id", nullable = false)
private Vehicle vehicle;
@OneToMany(mappedBy = "assetVehicle", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private Set<AssetVehicleMedia> media = new HashSet<>();
@OneToMany(mappedBy = "assetVehicle", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private Set<AssetVehicleDocument> documents = new HashSet<>();
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "asset_vehicle_branch",
joinColumns = @JoinColumn(name = "asset_vehicle_id"),
inverseJoinColumns = @JoinColumn(name = "branch_id")
)
private Set<Branch> branches = new HashSet<>();
//endregion
}
Репозиторий транспортного средства:
@Repository
public interface AssetVehicleRepository extends JpaRepository<AssetVehicle, UUID>, JpaSpecificationExecutor<AssetVehicle> {
Boolean existsByCompanyAndVehicleNumber(Company company, String vehicleNumber);
Optional<AssetVehicle> getByVehicleNumber(String vehicleNumber);
}
Сервис транспортного средства:
@Service
public class AssetVehicleServiceImpl implements AssetVehicleService {
@Autowired
CompanyService companyService;
@Autowired
AssetVehicleRepository assetVehicleRepository;
@Autowired
ModelMapper modelMapper;
@Override
public Boolean existsByCompanyVehicleNumber(UUID companyId, String vehicleNumber) {
Company company = companyService.findById(companyId);
return assetVehicleRepository.existsByCompanyAndVehicleNumber(company, vehicleNumber);
}
@Override
public AssetVehicle getByVehicleNumber(String vehicleNumber) {
return assetVehicleRepository.getByVehicleNumber(vehicleNumber)
.orElseThrow(() -> new NotFoundException("Транспортное средство не найдено с номером: " + vehicleNumber));
}
@Override
public AssetVehicleDto getByVehicleNumberDtoDto(String vehicleNumber) {
return modelMapper.map(getByVehicleNumber(vehicleNumber), AssetVehicleDto.class);
}
@Override
public Page<AssetVehicle> getAllAssets(Pageable pageable, AssetStatus status, UUID companyId, UUID ownerId) {
Specification<AssetVehicle> specification = Specification.where(AssetVehicleSpecification.hasStatus(status))
.and(AssetVehicleSpecification.hasCompany(companyId))
.and(AssetVehicleSpecification.hasOwner(ownerId));
return assetVehicleRepository.findAll(specification, pageable);
}
@Override
public Page<AssetVehicleDto> getAllAssetsDto(Pageable pageable, AssetStatus status, UUID companyId, UUID ownerId) {
Page<AssetVehicle> assets = getAllAssets(pageable, status, companyId, ownerId);
return assets.map(asset -> modelMapper.map(asset, AssetVehicleDto.class));
}
}
Я новичок в разработке на Spring Boot, до этого занимался мобильной разработкой (Android, iOS, Flutter). Я борюсь с этой проблемой уже около двух дней и пока не смог найти решение.
Я пробовал переименовать сущности и таблицы, но это не решило проблему.
Ранее у меня была одна таблица для активов. Я понял, что одна таблица может повлиять на производительность по мере роста базы данных, поэтому я решил разделить типы активов на отдельные таблицы, такие как транспортное средство, электроинструмент и генератор. На данный момент у меня есть только тип транспортного средства.
Ответ или решение
Причины возникновения PropertyReferenceException в Spring Data JPA
Ошибка, с которой вы столкнулись, а именно PropertyReferenceException: No property 'asset' found for type 'AssetVehicle'
, в первую очередь указывает на то, что Spring Data JPA не может найти свойство или метод, на которое вы ссылаетесь в вашем запросе или спецификации. В данном случае, это может быть связано с неправильным использованием методов репозитория, несоответствием между именем свойства и фактическими полями вашего класса AssetVehicle
, или отсутствием необходимой связи с другими сущностями.
Возможные причины возникновения данной ошибки:
-
Отсутствие поля в сущности: Ваша сущность
AssetVehicle
не содержит свойства с именемasset
. Проверьте, правильно ли вы указали название поля в методах репозитория или спецификации. Например, если вы пытаетесь использоватьasset
как часть имени метода (например,findByAsset(...)
), это вызовет сообщение об ошибке, так как такое свойство не существует. -
Неправильные имена методов в репозитории: В интерфейсе
AssetVehicleRepository
вы определили методexistsByCompanyAndVehicleNumber(...)
, однако, если вы используете метод, который ссылается наAsset
, это не будет работать, потому что в классеAssetVehicle
такого свойства нет. Убедитесь, что вы используете существующие методы и свойства, определенные в вашем репозитории. -
Ошибки в спецификациях: При использовании спецификаций в методе
getAllAssets
, убедитесь, чтоAssetVehicleSpecification
правильно настроен и что все указанные методы (такие какhasStatus
,hasCompany
,hasOwner
) действительно работают с полями, которые есть в классеAssetVehicle
. Если в этих методах вы ссылаетесь на полеasset
, которое отсутствует, это также вызовет ошибку.
Рекомендации по устранению ошибки
-
Проверьте все методы репозитория: Убедитесь, что все методы, которые вы используете, действительно соответствуют полям вашего класса
AssetVehicle
. Замените или поправьте названия методов, если они не соответствуют именам полей. -
Обновите спецификации: Если вы используете спецификации, убедитесь, что все используемые условия основаны на существующих свойствах класса
AssetVehicle
. Убедитесь, что вы не используете ссылки на несуществующие свойства. -
Логирование запросов: Включите более подробное логирование SQL-запросов Spring Data JPA для того, чтобы понять, какие именно запросы отправляются в базу данных и какие ошибки возникают при их выполнении.
-
Тестирование: Создавайте простые тесты для проверки работоспособности ваших методов репозитория. Это может помочь изолировать проблему и упростить отладку.
-
Проверьте связи с другими сущностями: Убедитесь, что отношения между сущностями корректны и на них нет ссылок на несуществующие свойства.
Заключение
Ошибка PropertyReferenceException
чаще всего связана с неправильными ссылками на поля в классах сущностей, неправильными именами методов в репозиториях или спецификациях. Путём тщательной проверки исходного кода на наличие ошибок и несоответствий, вы сможете быстро выявить и устранить проблему. Если затруднения сохраняются, рекомендуется обратиться к документации Spring Data JPA или сообществам разработчиков за дополнительной поддержкой.