2016-07-05 17 views
1

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 ...

+0

Ihre Frage zu lang ist, und unklar @JBNizet ändern. Welchen Code tust du, was erwartest du und was macht er? –

+0

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

+1

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. –

Antwort

1

@JBNizet

Es ist keine Transaktion Problem. 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.

Ich habe diese Antwort hinzugefügt, um Frage wie geschlossen zu markieren. Wenn ich jpa offen im Blick Transaktionen deaktiviert habe funktioniert wie erwartet.

Für Moderator bitte Autor Antwort