JSF, Spring, Hibernate --> Struktur!

C

crossib

Hallo,

benutze JSF, Hibernate und Spring

habe folgende JSF Seite (Auszug):

Code:
<h:form>
	<table>
	<tr>
	<td>Rolename:</td>
	<td><h:inputText value="#{roleController.role.rolename}" required="true"/></td>
	</tr>
	<tr>
	<td>Username:</td>
	<td><h:inputText value="#{roleController.user.username}" required="true"/></td>
	</tr>
	<tr>
	<td></td>
	<td><h:commandButton action="#{roleController.save}" value="Speichern"/></td>
	</tr>
	</table>
</h:form>


Und dann mein RoleController dazu:

Code:
public class RoleController {

	private BeanFactory beanFactory;
	private Role role;
	private User user;
	
	public RoleController() {
		beanFactory = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml"});
	}

	public Role getRole() {
		return role;
	}

	public void setRole(Role role) {
		this.role = role;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String save() {
		RoleServiceImpl roleService = (RoleServiceImpl) beanFactory.getBean("roleService");
		role.getUsers().add(user);
		user.setRole(role);
		roleService.save(role);
		return "success";
	}
}

Nun Funktioniert auch alles soweit, ich bin mir aber nichts ganz sicher ob alles korrekt strutkuriert ist, auch in Bezug auf Transaktionen.

Meine weiteren Files: Role, User (zwei ganz normale Beans), BasicDAOImpl, RoleDAO, RoleService und RoleServiceImpl

Vielen Dank im voraus!
 
Ich würde wie gesagt ein UserManagementService machen, der Rollen UND User verwaltet. Sonst trägst du ja einfach nur die DAOs nach oben.

Was definitiv nicht geht ist der manuelle Lookup und das halten der Referenz auf den AC. Wie man's richtig macht, steht hier.

Was die Transaktionen angeht ist davon ja nix zu sehen, von daher fällts schwer was dazu zu sagen ;)

REINHAUN!
 
Hallo,

hast du das in etwas so gemeint mit dem UserManagement?! Wäre für weitere Verbesserungsvorschläge und vor allem für Kritik offen :)

UserManagementService
Code:
package de.laliluna.example.service;

import java.util.List;

import de.laliluna.example.domain.Role;
import de.laliluna.example.domain.User;

public interface UserManagementService {
	public void saveRole(Role role);
	public void updateRole(Role role);	
	public Role findRoleById(Integer id);	
	public List<Role> findAllRole();
	public Role findRoleByUser(User user);
	
	public void saveUser(User user);
	public void updateUser(User user);
	public User findUserById(Integer id);
	public List<User> findAllUser();
	
	public void hibernateRoleAndUser(Role role, User user);
}

UserManagementServiceImpl
Code:
package de.laliluna.example.service;

import java.util.List;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import de.laliluna.example.domain.Role;
import de.laliluna.example.domain.RoleDao;
import de.laliluna.example.domain.User;
import de.laliluna.example.domain.UserDao;

public class UserManagementServiceImpl implements UserManagementService {

	private RoleDao roleDao;
	private UserDao userDao;
	
	public RoleDao getRoleDao() {
		return roleDao;
	}

	public void setRoleDao(RoleDao roleDao) {
		this.roleDao = roleDao;
	}
	
	public UserDao getUserDao() {
		return userDao;
	}

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	
	@Transactional(propagation=Propagation.REQUIRED)
	public void saveRole(Role role){
		roleDao.save(role);
	}
	
	@Transactional(propagation=Propagation.REQUIRED)
	public void updateRole(Role role) {
		roleDao.update(role);
	}
	
	@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
	public Role findRoleById(Integer id) {
		return roleDao.findById(id);
	}
	
	@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
	public List<Role> findAllRole(){
		return roleDao.findAll();
	}
	
	@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
	public Role findRoleByUser(User user) {
		return roleDao.findRoleByUser(user);
	}

	@Transactional(propagation=Propagation.REQUIRED)
	public void saveUser(User user){
		userDao.save(user);
	}
	
	@Transactional(propagation=Propagation.REQUIRED)
	public void updateUser(User user) {
		userDao.update(user);
	}
	
	@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
	public User findUserById(Integer id) {
		return userDao.findById(id);
	}
	
	@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
	public List<User> findAllUser(){
		return userDao.findAll();
	}
	
	@Transactional(propagation=Propagation.REQUIRED)
	public void hibernateRoleAndUser(Role role, User user){
		role.getUsers().add(user);
		user.setRole(role);
		roleDao.update(role);
	}
	
}

Vielen Dank wie immer im voraus :)
 
Mit den entsprechenden Kommentaren versehen ist das sicher ganz gut. Die komische Hibernate methode würde ich rauswerfen und die Funktionalität in die User Klasse schieben. Was du da nämlich implementierst ist Domänenfunktionalität und gehört demnach NICHT in Services.

Java:
public void addRole(Role role) {
  this.roles.add(role);
  role.getUsers().add(this);
}

Einen Großteil der @Transactional kannst du dir sparen indem du die Annotation einfach an die Klasse nagelst. Dann genügt es die Methoden mit @Transactional(readOnly=true) zu versehen, die nur lesen.

Gruß
Ollie
 
Hallo,

danke wieder für deine schnelle Antwort, was würd ich nur ohne dich machen ;). Bei der Expression und Managed Bean Integration habe ich den ersten Ansatz gewhält. Ich hoffe das ist okay.

Leider komme ich bei meinem Problem mit dem ApplicationContext nicht weiter. Besser gesagt ich kann aus dem Dokument nicht rauslesen was ich genau machen muss :(

Ich hoffe du kannst mir nochmal einen Ansatz geben.

EDIT:

Hab nun in die Web.xml folgendes eingefügt:

Code:
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath*:/applicationContext.xml</param-value>
	</context-param>
	
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	
	<listener>
		<listener-class>de.laliluna.example.Service.ContextStoreListener</listener-class>
	</listener>

dann folgende Klasse gemacht:

Code:
package de.laliluna.example.service;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class ContextStoreListener implements ServletContextListener {

	public void contextInitialized(ServletContextEvent evt) {
        ServletContext servletCtx = evt.getServletContext();
        WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletCtx);
        ApplicationContext context = webApplicationContext;
        StorageInitializer.setBeanFactory(context.getParentBeanFactory());
    }

    public void contextDestroyed(ServletContextEvent evt) {}
}

jetzt fehlt mir aber der Ansatz wie ich zum StorageInitializer komme. Ich weiß das ich ihn im applicationContext definieren muss, aber wo bekomme iche die Klasse StorageInitializer her? Und wie komme ich dann ran an das Zeug vom UserManagement?!
 
Zuletzt bearbeitet von einem Moderator:
Hoffentlich geht das jetzt nicht zu weit weg vom eigentlichen Thema, aber dieses JSF-Spring interessiert mich sehr. Wie schauts denn da mit der Performance aus? JSF soll ja schon einiges verbrauchen und Spring wirds wohl auch nicht beschleunigen.

Wenns danach geht, macht jede Zeile Code mehr die Anwendung langsamer. Performant ist auch relativ. Was hast du vor?

REINHAUN!
 
Naja diese Frameworks sind ja nicht unbedingt geeignet für die kleine Max Mustermann Homepage (Kanonen auf Spatzen), aber wie schaut es aus wenn man mal von ca 100-500 Personen ausgeht welche die Anwendung regelmäßig nutzen (z.B. als Intranetlösung).

Ist es möglich das ganze noch eingermaßen zügig laufen zu lassen ohne dass ich von jedem Server 3 Stück benötige (also 3x web-/app-/db-server)?
 
Okay, verstehe worauf du hinaus willst. Spring skaliert IMHO sowohl nach oben als auch nach unten. D.h. es sind auch kleine übersichtliche Anwendungen damit möglich. Wie es mit JSF ist weiß ich nicht genau. Aber grundsätzlich erfordet jede "neue" Technologie ein wenig Hirnschmalz damit man reinsteigt.

Was das Skalieren nach oben angeht, ist Spring selbst wohl Bullet-Proof (siehe Referenzen Liste auf der Spring Seite - z.B. VOCA - 8 Mrd. Transaktionen pro Tag), was dich aber sicher nicht hindert selbst völlig unperformanten Code zu schreiben ;)

REINHAUN!
 

Neue Beiträge

Zurück