Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Wtyczka może uzyskać dostęp do jakiejkolwiek bazy danych, jednak w tym rozdziale opisana zostanie tylko obsługa systemowej bazy danych.

Konfiguracja obiektów

W rozdziale Konfiguracja kontekstu wtyczki opisane zostało, w jaki sposób dodawać beany do kontekstu. Obsługa bazy danych bazować będzie na integracji SpringFramework i Hibernate. Opisana zostanie konfiguracja XML.

...

Code Block
languagehtml/xml
titleplugin-context.xml
<!-- adnotacje @Transactional -->
<tx:annotation-driven/>
 
<!-- TransactionManager -->
<bean name="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
	<property name="sessionFactory" ref="sessionFactory" />
</bean>

...

Przykład działania

Teraz należy stworzyć naszą encję:

...

Note

Nazwy tabel, kolumn i sequencerów nie powinny przekraczać 30 znaków (limit Oracle)

 

Zapis i odczyt naszego obiektu może wyglądać tak:

Code Block
languagejava
titleNoteService
@Service
@Transactional
public class NoteService {
 
	@Autowired
	private SessionFactory sessionFactory;
 
	public void saveNote(Note note){
		sessionFactory.getCurrentSession().save(note);
	}
 
	public Note getNote(Long id){
		return (Note) sessionFactory.getCurrentSession().get(Note.class, id);
	}
}
Tip

Jakiekolwiek zmiany dokonane we wtyczce nie wymagają restartu serwera. Nawet zmiany mappingu hibernate są widoczne po aktualizacji wtyczki.

Wykorzystanie w mappingu systemowych encji

Może się zdarzyć, że w naszej encji potrzebujemy mapping np. na użytkownika systemu. W takim wypadku musimy zaimportować mapping użytkownika, żeby nasza instancja SessionFactory miała wszystkie potrzebne do zapisu w bazie danych informacje.

Import mappingów z systemu odbywa się podczas konfiguracji SessionFactory Hibernate'a:

Code Block
languagehtml/xml
titleplugin-context.xml
<bean id="sessionFactory" class="com.suncode.pwfl.persistence.support.hibernate.SystemBaseSessionFactoryBean">
	<property name="packagesToScan" value="com.suncode.plugin.tutorial" />
	
	<!-- Musimy zaimportować całe drzewo zależności -->
	<property name="importedMappings">
		<array>
			<value>com.suncode.pwfl.administration.user.User</value>
			<value>com.suncode.pwfl.administration.user.UserGroup</value>
			<value>com.suncode.pwfl.administration.structure.Position</value>
			<value>com.suncode.pwfl.administration.structure.OrganizationalUnit</value>
			<value>com.suncode.pwfl.administration.structure.Role</value>
		</array>
	</property>
</bean>
Note

Aktualnie musimy samodzielnie wypisać wszystkie zależności, nawet te przejściowe. Jeżeli chcemy zaimportować tylko użytkownika, musimy zaimportować jeszcze 4 inne mappingi jak pokazano powyżej.

Planowane jest poprawienie sposobu importu mappingów.

 

Nasza zaktualizowana encja:

Code Block
languagejava
titleNote
@Entity
@Table(name = "pm_tutorial_note")
@SequenceGenerator(name = "note", sequenceName = "pm_tutorial_note_id")
public class Note {
 
	@Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "note")
	private Long id;
 
	@Column(length = 2000)
	private String text;
	
	@ManyToOne
    @JoinColumn(name = "user_id")
    @OnDelete(action = OnDeleteAction.CASCADE)
	private User user;
 
	// getters...
	// setters...
}
Tip

Dodanie obiektu użytkownika do naszej encji zaowocuje dodaniem klucza obcego w schemacie bazy danych. Niestety w takim wypadku nie będzie możliwe usunięcie użytkownika z systemu, dopóki nie zostaną usunięte wszystkie jego notatki.

Adnotacja:

@OnDelete(action = OnDeleteAction.CASCADE)

Dodaje kaskadowe usuwanie na poziomie schematu bazy danych (w przeciwieństwie do opcji cascade annotacji), dzięki czemu podczas usuwania użytkownika, usunięte zostaną wszystkie jego notatki.

Potrzebne jest inne rozwiązanie tego problemu, jednak aktualnie jest to jedyna opcja.