2017-04-25 1 views
0

J'ai deux entités, l'utilisateur et le fonctionnement et les deux entités ont une jointure entre eux:Joignez-vous à des entités avant d'enregistrer en utilisant la méthode POST

@Entity 
public class User implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long userId; 

    @Basic 
    private String username; 

    private String password; 

    //Getters and Setters 
} 

@Entity 
public class Operation implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long userId; 

    @ManyToOne 
    @JoinColumn(name = "user_id") 
    User user; 

    //Getters and Setters 

} 

Les deux entités a un dépôt aussi.

Dans mon contexte, l'entité utilisateur est chargée dans la portée Session (HttpSession) lorsque l'utilisateur (opérateur) a été connecté. Pour chaque opération de l'utilisateur sur le système, l'application enregistre cette opération dans le référentiel d'opérations.

Ma question est: Comment puis-je configurer l'entité utilisateur (se mettre en session) avant l'enregistrement dans la base de données?

Est-il possible de remplacer la méthode du référentiel?

EDIT 1:

L'opération est enregistré par le biais de l'interface web en utilisant le procédé HTTP POST. Je dois continuer à utiliser l'URI pour sauvegarder. Comme:

URI: http: // localhost: 9874/opérations DATA: { "name": "opération-name"}

Merci!

+0

voulez-vous dire redéfinissant la méthode de sauvegarde fournie par les données Spring JPA? – pvpkiran

+0

@pvpkiran exactement! Je pense que c'est le moyen de ma solution ... –

Répondre

3

Vous pouvez créer un pré gestionnaire de sauvegarde d'événement dans lequel vous pouvez définir l'association: vous peut alors créer un poste Spring Data Rest standard à http://localhost:9874/operations et il n'est pas nécessaire d'avoir un référentiel ou un contrôleur personnalisé.

http://docs.spring.io/spring-data/rest/docs/current/reference/html/#_writing_an_annotated_handler

@RepositoryEventHandler 
public class OperationEventHandler { 

    @HandleBeforeSave 
    public void handleOperationSave(Operation operation) { 

    } 
} 

Vous dites que l'utilisateur est stocké dans la session. Je suppose que vous n'utilisez pas Spring Security? Si vous êtes alors vous pouvez obtenir l'utilisateur actuel en utilisant un appel statique:

SecurityContextHolder.getContext().getAuthentication(); 

sinon vous auriez besoin essayer de fil HttpServletRequest à votre gestionnaire d'événements ou utilisez l'appel d'emballage statique comme indiqué dans les réponses à ces questions:

Spring: how do I inject an HttpServletRequest into a request-scoped bean?

De cela, vous pouvez obtenir le HttpSession.

Le câblage de tableau suivant illustre la HttpServletRequest exactement ce scénario

Spring Data Rest - How to receive Headers in @RepositoryEventHandler

de sorte que votre gestionnaire ressemble à:

@RepositoryEventHandler 
public class OperationEventHandler { 

    @Autowired 
    private HttPServletRequest request; 

    @HandleBeforeSave 
    public void handleOperationSave(Operation operation) { 

     User user = (User)request.getSession().getAttribute("userKey"); 
     operation.setUser(user); 
    } 
} 
+0

Merci Alan pour une bonne réponse! Oui, j'utilise SB Security. Désolé par ne dit pas cela ... Cependant, cela fonctionne très très bien pour moi mais j'avais ajouté une chose ... Était nécessaire ajouter une annotation @Component dans OperationEventHandler ... Autre chose, si j'appelle la méthode .save() à partir d'un référentiel manuellement ce gestionnaire sera appelé aussi? –

+1

Non. Il est spécifique SDR. Si vous n'avez pas besoin d'injecter quoi que ce soit, vous pouvez utiliser un écouteur d'événement JPA standard qui devrait fonctionner dans les deux cas. http://www.objectdb.com/java/jpa/persistence/event –

0

Créez une interface de référentiel personnalisé et écrivez une implémentation pour cela. par exemple.

public interface OperationRepositoryCustom { 

    <T extends Operation> T saveCustomized(Operation operation); 
} 

Votre classe d'implémentation ressemblerait à ceci.

public class OperationRepositoryImpl implements OperationRepositoryCustom{ 
    //You can autowire OperationRepository and other dependencies 

    @Autowired 
    OperationRepository operationRepository; 

    @Override 
    public Operation saveCustomized(Operation operation) { 
     //put your code to update operation with user and save it by calling operationRepository.save(). 
    } 
} 

être au courant de la convention de nommage, que votre implémentation personnalisée doit avoir le même nom que votre dépôt + Impl. Donc, si votre interface référentiel est appelé OperationRepository, l'interface de votre référentiel personnalisé doit être OperationRepositoryCustom et impl doit être nommé OperationRepositoryImpl

Hope it helps

+0

Merci pour la réponse rapide! J'oublie de parler une chose! J'utilise l'API REST pour enregistrer les opérations. Si j'utilise votre réponse, je vais briser mon application, non? –