название транспорта, фамилии рабочих, инстанции, фамилия агента, фамилия заказчика.
Стоит ли заморачиваться, и связывать через ключи таблицы в sql или можно это связать в самом коде через аннотации?
Какие могут быть последствия такой связи?
Какие есть нюансы?
delete()
и будет выброшено то исключение, которе вам нужно.
JPA does offer possibility to cascade operations (merge, persist, refresh, remove) to associated entities. Logic is in JPA and does not utilize database cascades.
There is no JPA standard compliant way to do cascades with database cascades.
There is no clean cut means to do this in JPA. The following will get you what you want... You can use CascadeType.DELETE, however this annotation only applies to the objects in the EntityManager, not the database. You want to be sure that ON DELETE CASCADE is added to the database constraint. To verify, you can configure JPA to generate a ddl file. Take a look at the ddl file, you'll notice that ON DELETE CASCADE is not part of the constraint. Add ON DELETE CASCADE to actual SQL in the ddl file, then update your database schema from the ddl. This will fix your problem .
Есть сертификат(Certificate), у него может быть много тегов (Tag).
Предполагается что в таблице тегов может быть куча дубликатов по имени, т.е. 3 сертификата могут иметь один и тот же тег "Java" ну или как-то так.
certificate_id | tag_id
, где вы сможете хранить данные. И соответственно, Как к entity присоединить список других entity и потом работать с ними и со списком?
@MappedSuperclass
. Вынести туда общие поля: username, password и др.Как хранить изображение? Насколько я знаю, их можно запихивать прямо в PostgreSQL, но я склоняюсь в сторону того, что изображения надо сохранять в ресурсы, а в бд хранить только ссылки.
@Entity
@Data
@NoArgsConstructor
@Table(name = "attachments")
public class Attachment {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long attachId;
private String attachTitle;
@Column(nullable = false, updatable = false)
private LocalDate uploadDate;
private String extension;
private String downloadLink;
}
@Repository
public interface AttachmentRepository extends JpaRepository<Attachment, Long> {}
public interface AttachmentService {
/**
* Загрузить новый файл
*
* @param file
* @param user
* @throws IOException
*/
Attachment addAttachment(MultipartFile file, User user) throws IOException;
/**
* Найти Вложение по его ID
*
* @param attachId
* @return
*/
Attachment findAttachById(Long attachId);
/**
* Скачать файл
*
* @param uploadYear
* @param fileName
* @return
* @throws MalformedURLException
*/
Resource loadFileAsResource(String uploadYear, String fileName) throws MalformedURLException;
}
@Service
@RequiredArgsConstructor
public class AttachmentServiceImpl implements AttachmentService {
private final AttachmentRepository attachmentRepository;
private final AppProperties appProperties;
private final FileTools fileTools;
/**
* Загрузить новый файл
*
* @param file
* @param user
* @throws IOException
*/
@Override
public Attachment addAttachment(MultipartFile file, User user) throws IOException {
// Создаем директорию если ее не существует
File uploadDir = new File(appProperties.getUploadPath());
// Если директория uploads не существует, то создаем ее
if (!uploadDir.exists()) {
uploadDir.mkdirs();
}
String curDate = LocalDateTime.now().toString();
// Создаем уникальное название для файла и загружаем файл
String fileName =
"attach_" + curDate + "_" + file.getOriginalFilename().toLowerCase().replaceAll(" ", "-");
file.transferTo(new File(uploadDir + "/" + fileName));
Attachment attachment = Attachment.builder()
.attachTitle(fileName)
.uploadDate(LocalDate.now())
.extension(fileTools.getFileExtension(file.getOriginalFilename()))
.downloadLink("/attachments/get/" + Year.now() + "/" + fileName)
.build();
attachmentRepository.save(attachment);
return attachment;
}
/**
* Найти Вложение по его ID
*
* @param attachId
* @return
*/
@Override
public Attachment findAttachById(Long attachId) {
return attachmentRepository
.findById(attachId)
.orElseThrow(() -> new AttachmentNotFoundException("Attachment not found!"));
}
/**
* Скачать файл
*
* @param fileName
* @return
* @throws MalformedURLException
*/
@Override
public Resource loadFileAsResource( String fileName)
throws MalformedURLException {
Path fileStorageLocation =
Paths.get(appProperties.getUploadPath()).toAbsolutePath().normalize();
Path filePath = fileStorageLocation.resolve(fileName).normalize();
return new UrlResource(filePath.toUri());
}
}
@Controller
@RequiredArgsConstructor
@RequestMapping("/attachments")
public class AttachmentController {
private final AttachmentService attachmentService;
private final UserService userService;
/**
* Загрузить новое вложение
*
* @param file
* @return
* @throws IOException
*/
@PostMapping(value = "/add", produces = "application/json")
@ResponseBody
public ResponseEntity<Map<String, String>> uploadAttachment(
@RequestPart(value = "file") MultipartFile file)
throws IOException {
Attachment attachment = attachmentService.addAttachment(file);
Map<String, String> attachmentStatus = new HashMap<>();
attachmentStatus.put("status", "ok");
attachmentStatus.put("attachId", attachment.getAttachId().toString());
return ResponseEntity.ok(attachmentStatus);
}
/**
* Получить ссылку на скачивание загруженного файла
*
* @param filename
* @param request
* @return
* @throws IOException
*/
@GetMapping("/get/{filename:.+}")
public ResponseEntity<Resource> serveFile(
@PathVariable String filename, HttpServletRequest request)
throws IOException {
Resource resource = attachmentService.loadFileAsResource(filename);
String contentType;
contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
if (contentType == null) {
contentType = "application/octet-stream";
}
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(contentType))
.header(
HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
}
}
CrudCourseRepository
Как JpaRepository производит обновление связей в таблице student_courses?
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
Насколько я понимаю, если я попытаюсь обновить сущность Student, передав в CrudStudentRepository#save() студента с пустым списком курсов, то в таблице student_courses будут удалены все записи, в которых фигурирует обновляемый студент, но по моему опыту этого не происходит. Как мне тогда удалять/обновлять эти записи?
CascadeType.All
или PERSIST & MERGE@Controller
@RequestMapping("/")
public class HelloController {
@GetMapping("/hello-world")
public String sayHello() {
return "hello_world";
}
}
Хочу сделать чтоб вход на страницы админа /adminPageProduct /adminPageUser
/admin/**
и на этом уровне ограничивать доступ, чем перечислять каждую ссылку в настройках конфигурации. А урл делать следующей структуры:/admin/products /admin/users
. Вам же в любом случае нужно закрыть доступ ко всей админке.antMatchers("/admin*")
A /config subdirectory of the current directory
The current directory
A classpath /config package
The classpath root
@Data @NoArgsConstructor
jdbc:mysql://localhost:3306/ticket_system?useUnicode=yes&characterEncoding=UTF-8
@Column(name = "`name`", length = 50,nullable = false)
Первый раз деплою. через идею все нормально отрабатывает, но при попытке задеплоить на vps выдает ошибку
hibernate.ddl-auto: validate
и если установлен, то импортировали ли вы ddl & dml на сервер. Или у вас он на production должен создать ddl сам?public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(App.class);
}
}