Erwartung - Lazy Loading sollte nicht aus Transaktion Bereich arbeiten (in Ruhe-Controller zum Beispiel), aber es funktioniert.Spring Boot - Transaction Management funktioniert nicht
Das Problem ist in @Transactional, nicht durch Feder Anwendung in meiner Konfiguration verwendet. Wie könnte ich es reparieren?
... Rest-Controller haben keine transaktionalen Methoden, sie verwenden nur specifiedServices zum Laden von Entitäten. Abhängige Sammlung, wenn es nicht in Dienst geladen wurde, sollte leer sein.
Anwendungsstarterklasse:
@SpringBootApplication
@EntityScan("com.vl.pmanager.domain.model")
@EnableJpaRepositories("com.vl.pmanager.domain.repository")
@EnableTransactionManagement
public class ProjectManagerApplication {
public static void main(String[] args) {
SpringApplication.run(ProjectManagerApplication.class, args);
}
}
Ich weiß, dass der Frühling Boot automatische Konfiguration Repositories und scannt Einheiten, aber ich hinzugefügt, in der Hoffnung ...
@EntityScan("com.vl.pmanager.domain.model")
@EnableJpaRepositories("com.vl.pmanager.domain.repository")
Auch ich versuchte @Transactional hinzufügen zu Repository-Schnittstelle, aber es hat nicht für mich funktioniert
package com.vl.pmanager.domain.repository;
import com.vl.pmanager.domain.model.Tag;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@Repository
@Transactional
public interface TagRepository extends PagingAndSortingRepository<Tag, Long> {
}
So
i gelöscht @Transactional aus dem Repository, erstellt anderen Service-Layer mit der Anmerkung zu verwalten und den Service zu injizieren an der Steuerung:
package com.vl.pmanager.domain.db.service.api;
import com.vl.pmanager.domain.model.Tag;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
public interface ITagManager {
Page<Tag> findAll(Pageable pageable);
Tag findOne(Long id);
}
// ======================== TAG SERVICE WRAPPED WITH TRANSACTION ==========================
package com.vl.pmanager.domain.db.service;
import com.vl.pmanager.domain.db.service.api.ITagManager;
import com.vl.pmanager.domain.model.Tag;
import com.vl.pmanager.domain.repository.TagRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class TagManager implements ITagManager {
@Autowired
private TagRepository tagRepository;
@Override
public Page<Tag> findAll(Pageable pageable) {
return tagRepository.findAll(pageable);
}
@Override
public Tag findOne(Long id) {
return tagRepository.findOne(id);
}
}
// ====================== REST CONTROLLER ============================
package com.vl.pmanager.web;
import com.vl.pmanager.domain.db.service.api.ITagManager;
import com.vl.pmanager.domain.model.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "/tags")
public class TagController {
private static final int DEFAULT_PAGE_SIZE = 50;
@Autowired
private ITagManager tagManager;
@RequestMapping(method = RequestMethod.GET, consumes = MediaType.ALL_VALUE)
public Page<Tag> getTags(@PageableDefault(size = DEFAULT_PAGE_SIZE) Pageable pageable) {
return tagManager.findAll(pageable);
}
@RequestMapping(value = "/{id}", method = RequestMethod.GET, consumes = MediaType.ALL_VALUE)
public Tag getTag(@PathVariable("id") Long id) {
return tagManager.findOne(id);
}
}
Tag Einheit hat einen Feld Sets Project auf andere Entität abgebildet mit @ManyToMany Beziehung mit FetchType fetch() Standard LAZY; so kann das Ergebnis nicht abhängige Entität enthalten, aber es ist.
I überwacht auch Protokolle DB:
// make request - load data using db service to controller level
Hibernate: select count(tag0_.id) as col_0_0_ from tag tag0_
Hibernate: select tag0_.id as id1_6_, tag0_.description as descript2_6_, tag0_.name as name3_6_ from tag tag0_ limit ?
// converting data to JSON automatically
Hibernate: select projectinf0_.tags as tags1_6_0_, projectinf0_.project_info as project_2_7_0_, projectinf1_.id as id1_4_1_, projectinf1_.description as descript2_4_1_, projectinf1_.name as name3_4_1_ from tag_project_info projectinf0_ inner join project_info projectinf1_ on projectinf0_.project_info=projectinf1_.id where projectinf0_.tags=?
Hibernate: select projectinf0_.tags as tags1_6_0_, projectinf0_.project_info as project_2_7_0_, projectinf1_.id as id1_4_1_, projectinf1_.description as descript2_4_1_, projectinf1_.name as name3_4_1_ from tag_project_info projectinf0_ inner join project_info projectinf1_ on projectinf0_.project_info=projectinf1_.id where projectinf0_.tags=?
Hibernate: select projectinf0_.tags as tags1_6_0_, projectinf0_.project_info as project_2_7_0_, projectinf1_.id as id1_4_1_, projectinf1_.description as descript2_4_1_, projectinf1_.name as name3_4_1_ from tag_project_info projectinf0_ inner join project_info projectinf1_ on projectinf0_.project_info=projectinf1_.id where projectinf0_.tags=?
Hibernate: select projectinf0_.tags as tags1_6_0_, projectinf0_.project_info as project_2_7_0_, projectinf1_.id as id1_4_1_, projectinf1_.description as descript2_4_1_, projectinf1_.name as name3_4_1_ from tag_project_info projectinf0_ inner join project_info projectinf1_ on projectinf0_.project_info=projectinf1_.id where projectinf0_.tags=?
Hibernate: select projectinf0_.tags as tags1_6_0_, projectinf0_.project_info as project_2_7_0_, projectinf1_.id as id1_4_1_, projectinf1_.description as descript2_4_1_, projectinf1_.name as name3_4_1_ from tag_project_info projectinf0_ inner join project_info projectinf1_ on projectinf0_.project_info=projectinf1_.id where projectinf0_.tags=?
Und ich weiß, gibt es nur 5 zusätzliche Anfragen, weil ich nur 5 abhängig haben auf TagPROJECT_INFO. Also als Schlussfolgerung meine Transaktionsebene nicht Transaktion verwalten. ... Ich habe überprüft, Datenquelle und transactionManager injizierenden Bohnen - eine wurde erstellt. Keine Fehler, keine Warnung in Startzeit oder zur Laufzeit ...
Ihre Frage zu lang ist, und unklar @JBNizet ändern. Welchen Code tust du, was erwartest du und was macht er? –
Erwartung - Lazy Loading sollte außerhalb des Transaktionsbereichs nicht funktionieren. aber es funktioniert in der Controller-Ebene. Scheint, dass @Transactional Annotation in meiner Konfiguration nicht funktioniert .... – Sergii
Es ist kein Transaktionsproblem. Suchen Sie in der Dokumentation nach der Eigenschaft spring.jpa.open-in-view, und legen Sie sie auf false fest, wenn Sie sie nicht möchten. –