Až Vám zčerná obrazovka, přejděte na Linux!

Proč používat Linux

pondělí 14. dubna 2008

(Ne)Qalita v bežném životě

Během víkendu jsem měl několik zajímavých postřehů ohledně kvality výrobků běžně potřeby.
Na prvním místě je autíčko mého syna, imitace klasického vojenského jeepu. Předpokládám, že uhodnete zemi původu. Ano, je to tak. Autíčko Made in China. Jako již poněkolikáté jsem vzal modelářské lepidlo na plasty a zalepil upadávající přední sklo (sklo tam samozřejmě není, jenom prázdný rám). Čínské plasty jsou pěkná fušeřina, trošku zatlačíte a křus. Tentokrát ale krom onoho rámu jsem zjistil, že je zadní náprava nějak podezřele posunutá jedním směrem.
Tak jsem vzal šroubovák, povolil jediný šroubek, co tam je, oddělal podvozek a čuměl jsem jak puk. V autíčku byl z mně neznámých důvodů osazený motorek spřevodovaný se zadní nápravou. A oba vstupy byly ustřižené! Pokud to mělo sloužit jako brzda nebo jako doraz (jiný význam nevidím), je to totální kravina. Holt, čínský výrobek, u něj se asi nemáme čemu divit.
Druhá hračka, která mne pěkně nadzvedla, byl silniční kužel v rozšiřující sadě (čtyři kužely, jeřáb, parní válec a nákla´dák) k vláčkodráze (ta kompatibilní s Maxim Wooden Toys), bohužel si už nepamatuju na výrobce, krabičku jsme už vyhodili. Každopádně jsme u této sestavy za pět kilo kvalitu jaksi očekával. Bohužel.
Buď máme doma takového ničitele, nebo prostě jenom ty hračky tak qalitní nejsou, ale dvě části kužele, vlastní kužel a podstava, byly k sobě jenom přilepeny a to něčím méně trvanlivým. Stačilo se o něj malinko opřít mimo osu kužele a podstava upadla. Musel jsem to k sobě přišroubovat.
Další "srandu" jsem si užil, když jsem koupil náhradní trafo k halogenovým bodovkám. Když jsem chtěl do svorkovnice přišroubovat měděné lanko, nešlo to. Důvod? Ve svorkovnici vypadající jak jednostranná "čokoládka" byl pod každým šroubem plech. Na tom by nebylo nic divného, kdyby ten plíšek nebyl napevno ukotvený z vnější strany. Přitahováním jsem tudíž lanko vytláčel a stačilo po dotažení za něj mírně zatáhnout a bylo venku :-(
Poslední zápich jsem zažil se satelitem od Koskomu. Po spadeném stropu, kdy jsme barák 7+2 muslei sestěhovat do dětského pokoje, který se zabednil, a do mojí nové pracovny o rozměrech 7x3m, ve které jsme museli měsíc vegetovat (čtyřčlenná rodina a naše hovawartí slečna, fakt legrace), byl satelit odpojený od sítě a pěkně zabalený před prachem. Po měsíci jsme ho vytáhli. Přívodní kabel jsme museli přecvaknout, protože se musela bourat příčka, kterou byl protažen a jíž konektor neprolezl. Po zapojení jsme ho museli zase nacvaknout. Byl šroubovací a tak jsem si na to troufl jenom se štípačkama a kombinačkama. Jenomže nám od té doby po televizi občas přeběhly pruhy. Napotřetí jsem k nám dostal ogaru, který nás zasatelitnil. Ten přišel a řekl, že je to pouhým nastavením video výstupu. Po dvou dnech odpojení prý koskom ztrácí konfiguraci!
No prostě hrůza a běs. Pokud mají nízké ceny přinést takové šmejdy, tak to ať se s cenovými závody honem přestane.

pátek 11. dubna 2008

IDEA a setter/getter generátor

IntelliJ IDEA umí generovat ohromné množství jednotlivých kusů kódu. Například toString() plugin generuje opravdu velice přehledně a inteligentně to, o co by se člověk musel starat. Navíc si můžete napsat několik vlastních šablon a ty potom podle potřeby generátoru vyměňovat.
Opačný extrém ale platí pro gettery a settery. IDEA je umí vygenerovat pro specifikované atributy, ale neumožňuje použít žádnou šablonu ani nakonfigurovat žádnou inteligenci.
Tak jsme hledal, jak toto opravit. A vygoogloval jsem feature request, který přesně o tomto mluví. takže doufám, že se toho brzo dočkáme. Ideálně v podobě pluginu či opravy stávajícího kódu.

Slovenčina je nádherná

Včera jsem se díval na ST 2. V reklamní přestávce v kriminálce Miami šel reklamní spot známý i u nás, na "konečně přípravek na hebké podpaží od nejmenované firmy", kde se děvče ptá svého milého, kterou část jejího těla má nejraději.
A reklama byla ve slovenštině. Na jejím konci jsem se musel smát, až jsem se za břicho popadal. Víte, jak se řekne slovensky podpaží? Podpazuší!
No řekněte, není ta slovečina úchvatný jazyk?

středa 9. dubna 2008

Hibernate a tabulky bez primárních klíčů

Jsou lidi, kteří tvrdí, že mít tabulku bez primárního klíče je nesmysl. A proto se bez něj Hibernate neumí pohnout. Já s nimi nesouhlasím.
Mějmež jednoduchý příklad: chceme uložit přichodivší fakturu do databáze. Faktura obsahuje hlavičku (kdo, kdy,...) a několik položek. Každá položka faktury má pevně danou strukturu. Z hlediska databázisty jednoduchý případ jak facka. Jedna tabulka pro fakturu (ID faktury, hlavička a stav), druhá pro položky (id faktury jako cizí klíč a atributy položky (cena, množství,...).
No jo, ale zkuste toto udělat v Hibernate! Jediná cesta, kterou jsem vygoogloval, je vytvořit fake_id pro každou položku každé faktury! FUJ! řeknou kování DBáci. A já s nimi.
Možná, že znáte jinou cestu. Rád se ji dozvím.

Hibernate a Primary Foreign Key

Tak jsem si dneska pořádně naběhl. Chtěl jsem si dvě tabulky provázat přes sdílený klíč, který byl v první Primary Key (tam záznam jako první vzniká) a po zpracování dat uložit do jiné tabulky řádek, jehož ID odpovídá tomu prvnímu, tedy bude hrít roli Primary a Foreign Key zároveň. Principiálně nic složitého.
Nechal jsem si v Idei vygenerovat příslušné anotace:

public class DataBindingEntity {
private long recordId;

@Id
@Column(name = "RECORD_ID", nullable = false)
public long getRecordId() {
return recordId;
}

public void setRecordId(long recordId) {
this.recordId = recordId;
}


private HibertestEntity hibertestByRecordId;

@OneToOne
@JoinColumn(name = "RECORD_ID", referencedColumnName = "ID", nullable = false)
public HibertestEntity getHibertestByRecordId() {
return hibertestByRecordId;
}

public void setHibertestByRecordId(HibertestEntity hibertestByRecordId) {
this.hibertestByRecordId = hibertestByRecordId;
}
...
}

public class HibertestEntity {
private long id;

@Id
@GeneratedValue(generator="triggerAssigned")
@GenericGenerator(name = "triggerAssigned",
strategy = "jpl.hibernate.util.TriggerAssignedIdentityGenerator")
@Column(name = "ID", nullable = false, length = 22)
public long getId() {
return id;
}

public void setId(long id) {
this.id = id;
}
private DataBindingEntity dataBindingById;

@OneToOne(mappedBy = "hibertestByRecordId")
public DataBindingEntity getDataBindingById() {
return dataBindingById;
}

public void setDataBindingById(DataBindingEntity dataBindingById) {
this.dataBindingById = dataBindingById;
}
...
}


Jenže jsem si parádně naběhl. Během inicializace sezení jsem chytil NPE:

13:04:59,125 ERROR [[acceptor]] Allocate exception for servlet acceptor
java.lang.NullPointerException
at org.hibernate.cfg.OneToOneSecondPass.doSecondPass(OneToOneSecondPass.java:135)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1130)
at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:296)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1286)


Zakomentování OneToOne propert na obou stranách problém vyřešilo. No, vyřešilo ... :-(

takže si to musím řešit ručně. Nedá se nic dělat.

pondělí 7. dubna 2008

IDEA 7, Hibernate a DB generovaná ID

Musím uznat, že ač je práce s Javím perzistorem Hibernate v IntelliJ IDEA celkem přímočará, dostanete se do stejných potíží, jaké u Hibernate mají i ostatní uživatelé. IDEA je přeci jenom vývojový nástroj, ikdyž geniální. Nic míň, ale také nic víc.
Potřeboval jsem qůli klastrovatelnosti nechat databázi generovat IDčka záznamů. V Oracle je to jednoduché, jde to naklikat v Oracle XE konzoli. ve výsledku asi nejkratší možný SQL záznam vypadá:

CREATE TABLE "HIBERTEST"
( "ID" NUMBER,
"DATA" BLOB,
CONSTRAINT "HIBERTEST_PK" PRIMARY KEY ("ID") ENABLE
)

CREATE OR REPLACE TRIGGER "BI_HIBERTEST"
before insert on "HIBERTEST"
for each row
begin
select "HIBERTEST_SEQ".nextval into :NEW.ID from dual;
end;


Pro pouhé uložení záznamu vám stačí nastavit IDčku hodnotu -1 (pro zachování nullable=false) a Oracle to přeplácne za Vás. Potíž nastane v okamžiku, kdy chcete s onou zaperzistentněnou beanou dál pracovat a mít v ní ono ID. Naštěstí bratr Google opět pomohl.
Jean-Pol Landrain napsal velice triviální a nádherný PostInsertGenerator, který to řeší velice elegantně. Podívejte se sami.
Pak stačí entitě v IDEA přidat anotaci

@GeneratedValue(generator="triggerAssigned")
@GenericGenerator(name="triggerAssigned",
strategy = "jpl.hibernate.util.TriggerAssignedIdentityGenerator")

a je vymalováno.

IDEA 7 aneb Tak dlouho jsem se bránil hibernate, až se ucho utrhlo

Nastoupil jsem do nového zaměstnání - do hradišťské firmy BARCO a začal psát J2EE aplikaci postavenou nad SQL. O hibernate jsem nechtěl ani slysšet, protože když jsem naposledy viděl jeho konfiguraci, jímala mne hrůza a běs.
Ale nainstaloval jsem si novou IntelliJ IDEA, IMHO nejlepší nástroj na vývoj aplikací v Javě, která podporu Hibernate v sobě obsahuje. Tak jsem to zkusil. V Oracle XE konzoli jsem si nadefinoval tabulku, dal do ní cvičně jeden řádek a zkoušel jsem, co s tím IDEA dokáže za kouzla. A byl jsem mile přeqapen.
Postup je velice jednoduchý. Ze všeho nejdřív si v projektu nadefinujte DataSource ukazující na onu tabulku (Menu->Tools->Data Sources..., nezapomeňte na Refresh Tables jako já :-) ). Pak vytvoříte v projektu nový modul typu Hibernate, zasociujete jej s Data Sources, přidáte Deskriptor (IDEA sama nabídne jediný možný ;-) ) a potvrdíte. Pro modul víc nepotřebujete.
Poté se už jenom v projektovém navigátoru přepnete do pohledu Java EE: Structure, kliknete na nový Hibernate projekt a v kontextovém menu vyberete Generate Persistence Mapping->By Database Schema a pak jen zíráte.